﻿package common;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
import java.util.regex.Pattern;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.logicalcobwebs.proxool.ConnectionInfoIF;
import org.logicalcobwebs.proxool.ProxoolFacade;
import org.logicalcobwebs.proxool.admin.SnapshotIF;

import sun.misc.BASE64Encoder;

import com.JMAuthenticator;
import com.jm.utils.StringHelper;

public class Utils {
	/**
	 * 一建構的時候就會附值給這個.
	 */
	private HttpServletRequest request;
	
	/**
	 * 建構子.
	 * @param req
	 */
	public Utils(HttpServletRequest req) {
		this.request = req;
	}

	public HttpServletRequest getRequest(){
		return this.request;
	}
	
	public HttpSession getSession(){
		return this.request.getSession();
	}
	
	public String getPagefilePath(){
		return System.getProperty("java.io.tmpdir") + "\\" + this.request.getSession().getId()+".page" ;
	}
	
	private boolean isMultipartContent() {
	    String contentType = request.getContentType();
        return ("post".equals(request.getMethod().toLowerCase()) && contentType != null && contentType.toLowerCase().startsWith("multipart"));
	}

	 /**
     * 從 rs 裡面取得指定欄位的 String 資料.
     * 
     * @param rs 傳送過來的 rs.
     * @param colName 欄位名稱.
     * @return 該筆資料 value.
     * @throws Exception
     */
    public String getRsString(ResultSet rs, String colName) throws Exception {
        String result = "";
        try {
            if (rs.getString(colName) != null) {
                result = rs.getString(colName).trim().replaceAll("<","&lt;");	//簡單防止數據庫xxl漏洞
            }
        } catch (Exception ex) {
            StringBuffer msg = new StringBuffer(this.getClass().getName()).append(" occurs error : ").append(ex.getMessage());
            throw new Exception(msg.toString());
        }
        return result;
    }

    /**
     * 從 rs 裡面取得指定欄位的 String 資料.
     * 
     * @param rs 傳過來的 rs.
     * @param col 第幾個欄位.
     * @return 該筆資料 value.
     * @throws Exception
     */
    public String getRsString(ResultSet rs, int col) throws Exception {
        String result = "";
        try {
            if (rs.getString(col) != null) {
                result = rs.getString(col).trim().replaceAll("<","&lt;");	//簡單防止數據庫xxl漏洞
            }
        } catch (Exception ex) {
            StringBuffer msg = new StringBuffer(this.getClass().getName()).append(" occurs error : ").append(ex.getMessage());
            throw new Exception(msg.toString());
        }
        return result;
    }
  
    /**
     * 格式化日期(yyyy/MM/dd hh:mm:ss).
     * 
     * @param date 傳入的日期
     * @return 格式化後的日期
     */
    public String formatDateTime(Date date) {
        String result = "";
        if (date != null) {
            result = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss").format(date);
            if (result.equals("1900/01/01")) {
                result = "";
            }
        }
        return result;
    }
    
    /**
     * @param pattern 日期格式
     * @param date 傳入的日期
     * @return 格式化後的日期
     * @author yanjie
     */
    public String formatDateTimes(Date date,String pattern) {
        String result = "";
        if (date != null) {
           result = new SimpleDateFormat(pattern).format(date);
           if (result.equals("1900/01/01")) {
                      result = "";
           }
        }
        return result;
    }


    /**
     * 兩個日期相差的天數.
     * @param str1 開始日期
     * @param str2 結束日期
     * @return 相差天數
     * @throws ParseException
     */
    public long diffDate(String str1, String str2) throws ParseException {
        SimpleDateFormat formater = new SimpleDateFormat("yyyy/MM/dd");
        Date date1 = formater.parse(str1);
        Date date2 = formater.parse(str2);
        long result = (date2.getTime() - date1.getTime()) / (1000 * 3600 * 24); // A day in milliseconds
        return result;
    }

    /**
     * 格式化日期(yyyy/MM/dd).
     * 
     * @param date 傳入的日期
     * @return 格式化後的日期
     */
    public String formatDate(Date date) {
        String result = "";
        if (date != null) {
            result = new SimpleDateFormat("yyyy/MM/dd").format(date);
            if (result.equals("1900/01/01")) {
                result = "";
            }
        }
        return result;
    }
    public final static int YEAR = Calendar.YEAR;
    public final static int MONTH = Calendar.MONTH;
    public final static int DATE = Calendar.DATE;
	public double diffDate(String str,String str1,String str2) throws ParseException {
		double result = 0;
			SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");  				
			if(str.equals("HH")) {
				Date date1 = formatter.parse(str1);
				Date date2 = formatter.parse(str2);
				result = (date2.getTime() - date1.getTime()) / (1000 * 3600.0);
			}			
		return result;
	}
    /**
     * 格式化日期, 並做加減日期功能.
     * 
     * @param date 傳入的日期.
     * @param field 日期欄位 Utils.YEAR, Utils.MONTH, Utils.DATE 三個值.
     * @param dateDiff 加減多少.
     * @return 格式化後的日期.
     */
    public String formatDate(Date date, int field, int dateDiff) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(field, dateDiff);
        return this.formatDate(cal.getTime());
    }

    /**
     * 格式化日期, 帶預設值, 如果預設值是 null 或 空白 會傳回 &nbsp;.
     * 
     * @param date 傳入日期.
     * @param def 預設值.
     * @return 格式化後的日期.
     */
    public String formatDate(Date date, String def) {
        String result = this.formatDate(date);
        if (result.trim().length() == 0) {
            result = (def == null || def.trim().length() == 0) ? "&nbsp;" : def;
        }
        return result;
    }
    /**
  　　 * 獲取前日期是星期几
  　　 *
  　　 * @param dt 傳入日期
  　　 * @return 前日期是星期几
  　　 */
    public String getWeekOfDate(Date dt) {
    	String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
    	Calendar cal = Calendar.getInstance();
    	cal.setTime(dt);
    	
    	int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
    	if (w < 0)
    	w = 0;
    	return weekDays[w];
    }
    /**
     * 取得網頁 String 參數.
     * @param name 參數名稱.
     * @return 傳回值.
     */
    public String getStringParam(String name) {
    	String result = "";
    	if(this.isUpload) {
        	 ArrayList list = (ArrayList) request.getAttribute(name);
             if (list != null && list.size() > 0) {
                 result = list.get(0).toString();
             }
        }
		 String temp = request.getParameter(name);
		 if (temp != null && temp.length() != 0) {
		     result = ascii(temp).trim();
		 }
    	return result;
    }
    

    /**
     * 取得網頁 String 參數, 帶預設值.
     * 
     * @param name 參數名稱.
     * @param def 預設值.
     * @return 傳回值.
     */
    public String getStringParam(String name, String def) {
        String result = this.getStringParam(name);
        return (result.length() == 0) ? def : result;
    }

    
    /**
     * 判斷日期類型(可以判斷所有日期格式).
     * 
     * @param date 日期數據.
     * @return 傳回值(true/false).
     */
    public boolean checkDate(String date) {
        Pattern p = Pattern
                .compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$");
        return p.matcher(date).matches();
    }

    /**
     * 取得網頁 String(日期) 參數.
     * 
     * @param name 參數名稱.
     * @return 傳回值.
     */
    public String getDateParam(String name) {
        String result = "";
        String temp = this.getStringParam(name);
        if (temp != null && temp.length() != 0) {
            result = ascii(temp);
            if (this.checkDate(result) == false) {
                result = "";
            }
        }
        return result;
    }

    
    /**
     * 取得網頁 String(日期) 參數, 帶預設值.
     * 
     * @param name 參數名稱.
     * @param def 預設值.
     * @return 傳回值.
     */
    public String getDateParam(String name, String def) {
        String result = this.getDateParam(name);
        return (result.length() == 0) ? def : result;
    }
    
    
    /**
     * 取得網頁 String[] 參數.
     * 
     * @param name 參數名稱.
     * @return 傳回值.
     */
	public String[] getStringParams(String name) {
	    String[] result = new String[0];
	    if(this.isUpload) {
	    	ArrayList temp = (ArrayList) request.getAttribute(name);
	        if (temp != null && temp.size() != 0) {
	            result = new String[temp.size()];
	            for (int i = 0; i < temp.size(); i++) {
	                result[i] = (temp.get(i) == null) ? "" : ascii(temp.get(i).toString()).trim();
	        }
	    }
	} else { 
	    String[] temp = request.getParameterValues(name);
	    if (temp != null && temp.length != 0) {
	        result = new String[temp.length];
	        for (int i = 0; i < temp.length; i++) {
	            result[i] = (temp[i] == null) ? "" : ascii(temp[i]).trim();
	            }
	        }
	    }
	    return result;
	}
	

    /**
     * 取得網頁 String 參數(大寫).
     * @param name
     * @return
     */
    public String getUpperStringParam(String name) {
        return getStringParam(name).toUpperCase();
    }

    
    /**
     * 取得網頁 String 參數(小寫).
     * 
     * @param name
     * @return
     */
    public String getLowerStringParam(String name) {
        return getStringParam(name).toLowerCase();
    }

    /**
     * 取得網頁 String[] 參數(大寫).
     * 
     * @param name
     * @return
     */
    public String[] getUpperStringParams(String name) {
        String[] result = getStringParams(name);
        for (int i = 0; i < result.length; i++) {
            result[i] = result[i].toUpperCase();
        }
        return result;
    }

    
    /**
     * 取得網頁 String[] 參數(小寫).
     * 
     * @param name
     * @return
     */
    public String[] getLowerStringParams(String name) {
        String[] result = getStringParams(name);
        for (int i = 0; i < result.length; i++) {
            result[i] = result[i].toLowerCase();
        }
        return result;
    }
    

    /**
     * 取得網頁 Int 參數.
     * 
     * @param name 參數名稱.
     * @return 傳回值.
     */
    public int getIntParam(String name) {
        int result = 0;
        String temp = this.getStringParam(name);
        if (temp != null && temp.length() != 0) {
            try {
                result = new Integer(temp).intValue();
            } catch (Exception ex) {
                result = 0;
            }
        }
        return result;
    }

    
    /**
     * 取得網頁 Int[] 參數.
     * 
     * @param name 參數名稱.
     * @return 傳回值.
     */
    public int[] getIntParams(String name) {
        int[] result = new int[0];
        String[] temp = this.getStringParams(name);
        if (temp != null && temp.length != 0) {
            result = new int[temp.length];
            for (int i = 0; i < temp.length; i++) {
                try {
                    result[i] = new Integer(temp[i]).intValue();
                } catch (Exception ex) {
                    result[i] = 0;
                }
            }
        }
        return result;
    }

    
    /**
     * 取得網頁 Double 參數.
     * 
     * @param name 參數名稱.
     * @return 傳回值.
     */
    public double getDoubleParam(String name) {
        double result = 0;
        String temp = this.getStringParam(name);
        if (temp != null && temp.length() != 0) {
            try {
                result = new Double(temp).doubleValue();
            } catch (Exception ex) {
                result = 0;
            }
        }
        return result;
    }
    /**
     * 取得網頁 Double 參數.
     * 
     * @param name 參數名稱.
     * @return 傳回值.
     */
    public double getDoubleParamPoints(String name) {
        double result = 0;
        String temp = this.getStringParam(name);
        if (temp != null && temp.length() != 0) {
            try {
            	temp = temp.replace(",","");
                result = new Double(temp).doubleValue();
            } catch (Exception ex) {
                result = 0;
            }
        }
        return result;
    }
    
    /**
     * 取得網頁 Double[] 參數.
     * 
     * @param name 參數名稱.
     * @return 傳回值.
     */
    public double[] getDoubleParams(String name) {
        double[] result = new double[0];
        String[] temp = this.getStringParams(name);
        if (temp != null && temp.length != 0) {
            result = new double[temp.length];
            for (int i = 0; i < temp.length; i++) {
                try {
                    result[i] = new Double(temp[i]).doubleValue();
                } catch (Exception ex) {
                    result[i] = 0;
                }
            }
        }
        return result;
    }

    /** ***************************************************************************  
     * 處理圖片上傳編碼過的 form 的傳遞參數. 
     **************************************************************************** */
    private boolean isUpload = false;
    public void parseUploadRequest() {
    	if (!isUpload && this.isMultipartContent()) {
	        try {
	            Map<String, List> map1 = new HashMap<String, List>(); // 記錄文件信息
	            Map<String, List> map2 = new HashMap<String, List>(); // 記錄文件名
	            Map<String, List> map3 = new HashMap<String, List>(); // 記錄文件後綴名
	            Map<String, List> map4 = new HashMap<String, List>(); // 記錄文字信息
	            int totalByte = request.getContentLength();
	            if (totalByte > 0) {
	                // 將上傳的內容讀出來 放入 buffer.
	                byte[] buffer = new byte[totalByte];
	                int totalRead = 0;
	                int readByte = 0;
	                for (; totalRead < totalByte; totalRead += readByte) {
	                        readByte = request.getInputStream().read(buffer, totalRead, totalByte - totalRead);
	                }
	                // 開始處理.
	                String str = new String(buffer);
	                String contentType = request.getContentType();
	                String boundary = "--" + contentType.substring(contentType.lastIndexOf("=") + 1, contentType.length());
	                String[] array = str.split(boundary);
	                String temp = null;
	                int location = 0;
	                int tpLen = array[0].length() + boundary.length();
	                for (int i = 1; i < array.length - 1; i++) {
	                    temp = array[i];
	                    int start = temp.indexOf("name=\"");
	                    if (start != -1) {
	                        String fieldValue = "";
	                        // 取得欄位名稱.
	                        int end = temp.indexOf("\"", start + 6); 
	                        String fieldName = temp.substring(start + 6, end);
	                        // 是否為檔案.  
	                        start = temp.indexOf("filename=\"");
	                        if (start != -1) {
	                            // 文件路徑
	                            String filePath = temp.substring(start + 10, temp.indexOf("\"", start + 10));
	                            String fileName = filePath.substring(filePath.lastIndexOf("\\") + 1);
	                            int tp1 = fileName.getBytes().length ;
	                            byte[] tp2  =  new byte[tp1];
	                            location = tpLen+start + 10 + filePath.getBytes().length-tp1;
	                            for (int j = 0; j < tp1 && j < totalByte; j++) {
	                            	tp2[j] = buffer[location + j];
	                            }
	                            fileName = new String(tp2,"UTF-8");
	                            String fileExtName = filePath.substring(filePath.lastIndexOf(".") + 1);
	                            // String fileType = temp.substring(temp.indexOf("Content-Type: ") + 14, temp.indexOf("\r\n\r\n"));
	                            // 文件資料
	                            start = temp.indexOf("\r\n\r\n", start);
	                            fieldValue = temp.substring(start + 4);
	                            fieldValue = fieldValue.substring(0, fieldValue.lastIndexOf("\n") - 1);
	                            int len = fieldValue.getBytes().length;
	                            byte[] file = new byte[len];
	                            location = temp.indexOf("filename=\"") + tpLen;
	                            tpLen += temp.getBytes().length + boundary.length();
	                            for (int j = location; j < totalByte - 2; j++) {
	                                if (buffer[j] == 13 && buffer[j + 2] == 13) {
	                                    location = j + 4;
	                                    break;
	                                }
	                            }
	                            for (int j = 0; j < len && j < totalByte; j++) {
	                                file[j] = buffer[location + j];
	                            }
	                            // 如果此欄位還沒出現過.
	                            if (!map1.containsKey(fieldName)) {
	                                // 產生 暫存的map容器.
	                                map1.put(fieldName, new ArrayList<byte[]>());                                
	                                map2.put(fieldName, new ArrayList<String>());
	                                map3.put(fieldName, new ArrayList<String>());
	                                // 順便放到request裡面.
	                                request.setAttribute(fieldName, (ArrayList<byte[]>) map1.get(fieldName));
	                                request.setAttribute(fieldName + "_NAME", (ArrayList<String>) map2.get(fieldName));
	                                request.setAttribute(fieldName + "_EXTEND", (ArrayList<String>) map3.get(fieldName));
	                            }
	                            
	                            // 文件信息
	                            List<byte[]> newList1 = (ArrayList<byte[]>) map1.get(fieldName);
	                            newList1.add(file);
	                            map1.put(fieldName, newList1);
	                            // 文件名稱
	                            List<String> newList2 = (ArrayList<String>) map2.get(fieldName);
	                            newList2.add(fileName);
	                            map2.put(fieldName, newList2);
	                            // 文件後綴名
	                            List<String> newList3 = (ArrayList<String>) map3.get(fieldName);
	                            newList3.add(fileExtName);
	                            map3.put(fieldName, newList3);
	                            
	                        } else {
	                            start = temp.indexOf("\r\n\r\n", 0);
	                            String strFieldValue = temp.substring(start + 4);
	                            strFieldValue = strFieldValue.substring(0, strFieldValue.lastIndexOf("\n") - 1);
	                            // String fileType = temp.substring(temp.indexOf("Content-Type: ") + 14, temp.indexOf("\r\n\r\n"));
	                            int len = strFieldValue.getBytes().length;
	                            byte[] file = new byte[len];
	                            location = temp.indexOf("name=\"") + tpLen;
	                            tpLen += temp.getBytes().length + boundary.length();
	                            for (int j = location; j < totalByte - 2; j++) {
	                                if (buffer[j] == 13 && buffer[j + 2] == 13) {
	                                    location = j + 4;
	                                    break;
	                                }
	                            }
	                            for (int j = 0; j < len && j < totalByte; j++) {
	                                file[j] = buffer[location + j];
	                            }
	                            strFieldValue = new String(file, "UTF-8");
	                            
	                            if (!map4.containsKey(fieldName)) {
	                                // 產生暫存的容器
	                                map4.put(fieldName, new ArrayList<String>());
	                                // 順便放入 request
	                                request.setAttribute(fieldName, (ArrayList<String>) map4.get(fieldName));
	                            }
	                            List<String> newList = (ArrayList<String>) map4.get(fieldName);
	                            newList.add(strFieldValue);
	                            map4.put(fieldName, newList);
	                        }
	                    }
	                }
	            }
	            this.isUpload = true;
	        } catch (Exception ex) {
	            System.out.println("=== 上傳元件出錯 ===");
	            this.recordException(ex);
	        } 
    	}
    }
    
    // 以下是上傳檔案的相關方法
    
    public void saveFile(String dir, String fileName, byte[] date) throws Exception{
    	String dirName = System.getProperty("user.dir"); 
    	// 去掉bin, 加上 webapps\\userData 並作檢查 
    	dirName = dirName.substring(0, dirName.length() - 3) + "\\webapps\\userData";
    	File file = new File(dirName);
    	if (!file.exists()) {
    		file.mkdir();		
    	}
    	dirName = dirName + "\\" + dir;
    	file = new File(dirName);
    	if (!file.exists()) {
    		file.mkdir();
    	}

 	    FileOutputStream output = new FileOutputStream(dirName + "\\" + fileName);
 	    output.write(date);
 	    output.close();
    }

    public byte[] getFileParam(String name) {
        byte[] result = null;
        List temp = (ArrayList) request.getAttribute(name);
        if (temp != null && temp.size() > 0) {
            result = (byte[]) temp.get(0);
        }
        return result;
    }

    public byte[][] getFileParams(String name) {
        List temp = (ArrayList) request.getAttribute(name);
        int k = (temp != null && temp.size() > 0) ? temp.size() : 0;
        byte[][] result = new byte[k][1];
        for (int i = 0; i < k; i++) {
            result[i] = (byte[]) temp.get(i);
        }
        return result;
    }

    //文件名稱
    public String getFileNameParam(String name) {
        String result = "";
        ArrayList temp = (ArrayList) request.getAttribute(name + "_NAME");
        if (temp != null && temp.size() != 0) {
            result = (temp.get(0) == null) ? "" : ascii(temp.get(0).toString()).trim();
        }
        return result;
    }

    public String[] getFileNameParams(String name) {
        String[] result = new String[0];
        ArrayList temp = (ArrayList) request.getAttribute(name + "_NAME");
        if (temp != null && temp.size() != 0) {
            result = new String[temp.size()];
            for (int i = 0; i < temp.size(); i++) {
                result[i] = (temp.get(i) == null) ? "" : ascii(temp.get(i).toString()).trim();
            }
        }
        return result;
    }

    //文件後綴名.
    public String getFileExtParam(String name) {
        String result = "";
        ArrayList temp = (ArrayList) request.getAttribute(name + "_EXTEND");
        if (temp != null && temp.size() != 0) {
            result = (temp.get(0) == null) ? "" : ascii(temp.get(0).toString()).trim();
        }
        return result;
    }

    public String[] getFileExtParams(String name) {
        String[] result = new String[0];
        ArrayList temp = (ArrayList) request.getAttribute(name + "_EXTEND");
        if (temp != null && temp.size() != 0) {
            result = new String[temp.size()];
            for (int i = 0; i < temp.size(); i++) {
                result[i] = (temp.get(i) == null) ? "" : ascii(temp.get(i).toString()).trim();
            }
        }
        return result;
    }

    /**
     * 判斷 int[] 裡面是否有 傳入值.
     * 
     * @param array 傳入的 int[].
     * @param j 傳入值.
     * @return true / false.
     */
    public boolean inIntArray(int[] array, int j) {
        boolean result = false;
        for (int i = 0; i < array.length; i++) {
            if (array[i] == j) {
                result = true;
                break;
            }
        }
        return result;
    }
    private final String[] hex = { "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E",
            "4F", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F", "A0", "A1",
            "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF", "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF", "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF", "F0", "F1", "F2", "F3", "F4",
            "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF" };

    private String escape(String s) {
        StringBuffer sbuf = new StringBuffer();
        int len = s.length();
        for (int i = 0; i < len; i++) {
            int ch = s.charAt(i);
            if (ch == ' ') { // space : map to '+'
                sbuf.append('+');
            } else if ('A' <= ch && ch <= 'Z') { // 'A'..'Z' : as it was
                sbuf.append((char) ch);
            } else if ('a' <= ch && ch <= 'z') { // 'a'..'z' : as it was
                sbuf.append((char) ch);
            } else if ('0' <= ch && ch <= '9') { // '0'..'9' : as it was
                sbuf.append((char) ch);
            } else if (ch == '-' || ch == '_' // unreserved : as it was
                    || ch == '.' || ch == '!' || ch == '~' || ch == '*' || ch == '\'' || ch == '(' || ch == ')') {
                sbuf.append((char) ch);
            } else if (ch <= 0x007F) { // other ASCII : map to %XX
                sbuf.append('%');
                sbuf.append(hex[ch]);
            } else { // unicode : map to %uXXXX
                sbuf.append('%');
                sbuf.append('u');
                sbuf.append(hex[(ch >>> 8)]);
                sbuf.append(hex[(0x00FF & ch)]);
            }
        }
        return sbuf.toString();
    }

    /**
     * Javascript 的 unescape, 可用於中文 hyperlink 時.
     * 
     * @param s 傳入值.
     * @return 編碼後的值.
     */
    public String unescape(String s) {
        StringBuffer sbuf = new StringBuffer();
        int len = s.length();
        for (int i = 0; i < len; i++) {
            int ch = s.charAt(i);
            if ('A' <= ch && ch <= 'Z') { // 'A'..'Z'
                sbuf.append((char) ch);
            } else if ('a' <= ch && ch <= 'z') { // 'a'..'z'
                sbuf.append((char) ch);
            } else if ('0' <= ch && ch <= '9') { // '0'..'9'
                sbuf.append((char) ch);
            } else if (ch == ' ') { // space
                sbuf.append('+');
            } else if (ch == '-' || ch == '_' // unreserved
                    || ch == '.' || ch == '!' || ch == '~' || ch == '*' || ch == '\'' || ch == '(' || ch == ')') {
                sbuf.append((char) ch);
            } else if (ch <= 0x007f) { // other ASCII
                sbuf.append('%');
                sbuf.append(hex[ch]);
            } else if (ch <= 0x07FF) { // non-ASCII <= 0x7FF
                sbuf.append('%');
                sbuf.append(hex[0xc0 | (ch >> 6)]);
                sbuf.append('%');
                sbuf.append(hex[0x80 | (ch & 0x3F)]);
            } else { // 0x7FF < ch <= 0xFFFF
                sbuf.append('%');
                sbuf.append(hex[0xe0 | (ch >> 12)]);
                sbuf.append('%');
                sbuf.append(hex[0x80 | ((ch >> 6) & 0x3F)]);
                sbuf.append('%');
                sbuf.append(hex[0x80 | (ch & 0x3F)]);
            }
        }
        return sbuf.toString();
    }

    /**
     * 處理全形半形.
     * 
     * @param s
     * @return
     */
    private String ascii(String s) {
        StringBuffer result = new StringBuffer();
        String asciiTable = "\'\"`` \'.^!\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
        String big5Table = "%u2019%u201D%u2018%u2035%u3000%u3001%u3002%uFE3F%uFF01%uFF02%uFF03%uFF04%uFF05%uFF06%uFF07%uFF08%uFF09%uFF0A%uFF0B%uFF0C%uFF0D%uFF0E%uFF0F%uFF10%uFF11%uFF12%uFF13%uFF14%uFF15%uFF16%uFF17%uFF18%uFF19%uFF1A%uFF1B%uFF1C%uFF1D%uFF1E%uFF1F%uFF20%uFF21%uFF22%uFF23%uFF24%uFF25%uFF26%uFF27%uFF28%uFF29%uFF2A%uFF2B%uFF2C%uFF2D%uFF2E%uFF2F%uFF30%uFF31%uFF32%uFF33%uFF34%uFF35%uFF36%uFF37%uFF38%uFF39%uFF3A%uFF3B%uFF3C%uFF3D%uFF3E%uFF3F%uFF40%uFF41%uFF42%uFF43%uFF44%uFF45%uFF46%uFF47%uFF48%uFF49%uFF4A%uFF4B%uFF4C%uFF4D%uFF4E%uFF4F%uFF50%uFF51%uFF52%uFF53%uFF54%uFF55%uFF56%uFF57%uFF58%uFF59%uFF5A%uFF5B%uFF5C%uFF5D%uFF5E";
        char[] ary = s.toCharArray();
        for (int i = 0; i < ary.length; i++) {
            String val = escape(Character.toString(ary[i]));
            int j = big5Table.indexOf(val);
            result.append((((j > -1) && (val.length() == 6)) ? asciiTable.charAt(j / 6) : s.charAt(i)));
        }
        return result.toString();
    }

    /**
     * 四捨五入.
     * 
     * @param var 傳入值.
     * @param dot 小數幾位.
     * @return 回傳值.
     */
    public double round(double var, int dot) {
        return Math.round(var * Math.pow(10, dot)) / Math.pow(10, dot);
    }

    /**
     * 取得新的 tsn 編號.
     * 
     * @param server Server name.
     * @param database Database name.
     * @param table Table name.
     * @return 傳回新的tsn.
     * @throws Exception
     */
    public String getNewTsn(String server, String database, String table) {
        String result = "";
        StringBuffer sql = new StringBuffer("select max(Tsn+1) from ").append(database).append("..").append(table);
        try {
            ResultSet rs = this.executeQuery(server, sql.toString());
            rs.next();
            result = rs.getString(1);
            if (result == null) {
                result = "1";
            }
        } catch (Exception e) {
            // rollback();
            System.out.println("\n- " + formatDateTime(new Date()));
            System.out.println("- Utils.getNewTsn() 發生錯誤 !!");
            System.out.println("- Server Name : " + server);
            System.out.println("- Database Name : " + database);
            System.out.println("- Table Name : " + table);
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 取得某個單的新單號.
     * 
     * @param server
     * @param database
     * @param table
     * @param column
     * @param prefix
     * @return
     * @throws Exception
     */
    public String getNewBillNo(String server, String database, String table, String column, String prefix) throws Exception {
        String result = null;
        SimpleDateFormat dateFormater = new SimpleDateFormat("yyMM");
        String yearMonth = dateFormater.format(new Date());
        String sql = "select top 1 substring(" + column + ", 5, 4) from " + database + ".." + table + " where substring(" + column + ", 1, 4) = '" + yearMonth + "' order by " + column + " desc";
        try {
            ResultSet rs = this.executeQuery(server, sql.toString());
            if (rs.next()) {
                DecimalFormat decimalFormater = new DecimalFormat("0000");
                result = new StringBuffer(yearMonth).append(decimalFormater.format(rs.getLong(1) + 1)).toString();
            } else {
                result = new StringBuffer(yearMonth).append("0001").toString();
            }
        } catch (Exception ex) {
            // rollback();
            System.out.println("\n- " + formatDateTime(new Date()));
            System.out.println("- Utils.getNewBillNo() 發生錯誤 !!");
            System.out.println("- Server Name : " + server);
            System.out.println("- Database Name : " + database);
            System.out.println("- Table Name : " + table);
            System.out.println("- Column Name : " + column);
            System.out.println("- Prefix Name : " + prefix);
            ex.printStackTrace();
        }
        return result;
    }

    public String getNewSeqNo(String server, String database, String table, String billColumnName, String seqColumnName, String billNo) throws Exception {
        String result = null;
        String sql = "select top 1 " + seqColumnName + " + 1 from " + database + ".." + table + " where " + billColumnName + " = '" + billNo + "' order by " + seqColumnName + " desc";
        try {
            ResultSet rs = this.executeQuery(server, sql.toString());
            if (rs.next()) {
                result = rs.getString(1);
            } else {
                result = "1";
            }
        } catch (Exception ex) {
            // rollback();
            System.out.println("\n- " + formatDateTime(new Date()));
            System.out.println("- Utils.getNewSeqNo() 發生錯誤 !!");
            System.out.println("- Server Name : " + server);
            System.out.println("- Database Name : " + database);
            System.out.println("- Table Name : " + table);
            System.out.println("- Bill Column Name : " + billColumnName);
            System.out.println("- Seq Column Name : " + seqColumnName);
            System.out.println("- Bill No : " + billNo);
            ex.printStackTrace();
        }
        return result;
    }
    private static final int GET = 0; // Get method.
    private static final int POST = 1; // Post method.

    private String getResponse(String url, int method, NameValuePair... params) throws Exception {
        StringBuffer response = new StringBuffer();
        HttpClient client = new HttpClient(); // HTTPClient.
        String encoing = "UTF-8"; // charset encoding.
        int statusCode = -1;
        BufferedReader br;
        String line;
        if (method == GET) {
            GetMethod get = new GetMethod(url);
            statusCode = client.executeMethod(get);
            if (statusCode != -1) {
                br = new BufferedReader(new InputStreamReader(get.getResponseBodyAsStream(), encoing));
                while ((line = br.readLine()) != null) {
                    response.append(line).append(System.getProperty("line.separator"));
                }
            }
            get.releaseConnection();
            return response.toString();
        } else if (method == POST) {
            PostMethod post = new PostMethod(url);
            post.setRequestBody(params);
            statusCode = client.executeMethod(post);
            if (statusCode != -1) {
                br = new BufferedReader(new InputStreamReader(post.getResponseBodyAsStream(), encoing));
                while ((line = br.readLine()) != null) {
                    response.append(line).append(System.getProperty("line.separator"));
                }
            }
            post.releaseConnection();
            return response.toString();
        } else {
            throw new Exception("Method getResponse() occur Exception : ");
        }
    }
    public static final int URL = 2;
    public static final int TEXT = 3;
    public static final int HTML = 4;

    /**
     * mail的發送
     * 
     * @param toMail
     * @param sub
     * @param text
     * @param property
     * @throws Exception
     */
    public void sendMail(String from, String to, String subject, String str, int contentType) throws Exception {
    	Session session = null;
    	if(subject.length() > 40) {
    		subject = subject.substring(0, 40);
    	}
    	Vector file = new Vector();
        BASE64Encoder enc = new BASE64Encoder();
        Properties props = new Properties();
        if(this.isAtuMail(to)){
	        props.put("mail.smtp.host", "mail"); // mail host.
	        props.put("mail.smtp.auth","true");
	        session = Session.getInstance(props, new JMAuthenticator());
        }else{
        	props.put("mail.smtp.host", "webmail.jmknit.com"); // mail host.
        	session = Session.getDefaultInstance(props, null);
        }
        
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress("exchgadmin@mail.JMKNIT.com"));
        //message.setFrom(new InternetAddress("sime@mail.JMKNIT.com"));
        message.setRecipients(Message.RecipientType.TO, to);
        message.setSubject("=?big5?B?" + enc.encode(subject.getBytes()) + "?=");
        MimeMultipart multiPart = new MimeMultipart();
        MimeBodyPart bodyPart = new MimeBodyPart();
        
        if (contentType == URL) {
            // str 如果是傳入 url要先經過處理.
            String[] x = str.split("\\?");
            String url = x[0]; // 網址.
            NameValuePair[] nvPair = new NameValuePair[0];
            if (x.length > 1) { // 有帶參數. 湊成 NameValuePair[].
                String[] y = x[1].split("&");
                nvPair = new NameValuePair[y.length];
                for (int i = 0; i < y.length; i++) {
                    String[] z = y[i].split("=");
                    if (z.length > 1) {
                        nvPair[i] = new NameValuePair(z[0], z[1]);
                    } else {
                        nvPair[i] = new NameValuePair(z[0], "");
                    }
                }
            }
            String content = this.getResponse(url, Utils.GET, nvPair);
            bodyPart.setContent(content, "text/html;charset=utf-8");
        } else if (contentType == TEXT) {
            bodyPart.setText(str);
        } else if (contentType == HTML) {
        	bodyPart.setContent(str, "text/html;charset=utf-8");
        }
        multiPart.addBodyPart(bodyPart);
        message.setContent(multiPart);
        message.saveChanges();
        Transport.send(message);
    }
    /**
     * mail的發送
     * 
     * @param toMail
     * @param sub
     * @param text
     * @param property
     * @throws Exception
     */
    public void sendMail(String from, String to, String subject, String str, int contentType, String fname) throws Exception {
    	Session session = null;
    	if(subject.length() > 40) {
    		subject = subject.substring(0, 40);
    	}
    	Vector file = new Vector();
    	for(int i = 0;i < fname.split(";").length; i++) {
    		file.addElement(fname.split(";")[i]);
    	}
        BASE64Encoder enc = new BASE64Encoder();
        Properties props = new Properties();
        if(this.isAtuMail(to)){
	        props.put("mail.smtp.host", "mail"); // mail host.
	        props.put("mail.smtp.auth","true");
	        session = Session.getInstance(props, new JMAuthenticator());
        }else{
        	props.put("mail.smtp.host", "webmail.jmknit.com"); // mail host.
        	session = Session.getDefaultInstance(props, null);
        }
        
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress("exchgadmin@mail.JMKNIT.com"));
        message.setRecipients(Message.RecipientType.TO, to);
        message.setSubject("=?big5?B?" + enc.encode(subject.getBytes()) + "?=");
        MimeMultipart multiPart = new MimeMultipart();
        MimeBodyPart bodyPart = new MimeBodyPart();
        Enumeration efile = file.elements();
        while(efile.hasMoreElements()) {
	        MimeBodyPart mbp =new MimeBodyPart();
	        String filename = efile.nextElement().toString();
	        FileDataSource fds=new FileDataSource(filename);
	        mbp.setDataHandler(new DataHandler(fds));
	        mbp.setFileName(fds.getName());
	        multiPart.addBodyPart(mbp);
        }
        file.removeAllElements();
        message.setContent(multiPart);
        if (contentType == URL) {
            // str 如果是傳入 url要先經過處理.
            String[] x = str.split("\\?");
            String url = x[0]; // 網址.
            NameValuePair[] nvPair = new NameValuePair[0];
            if (x.length > 1) { // 有帶參數. 湊成 NameValuePair[].
                String[] y = x[1].split("&");
                nvPair = new NameValuePair[y.length];
                for (int i = 0; i < y.length; i++) {
                    String[] z = y[i].split("=");
                    if (z.length > 1) {
                        nvPair[i] = new NameValuePair(z[0], z[1]);
                    } else {
                        nvPair[i] = new NameValuePair(z[0], "");
                    }
                }
            }
            String content = this.getResponse(url, Utils.GET, nvPair);
            bodyPart.setContent(content, "text/html;charset=utf-8");
        } else if (contentType == TEXT) {
            bodyPart.setText(str);
        }
        file.removeAllElements();
        multiPart.addBodyPart(bodyPart);
        message.setContent(multiPart);
        message.saveChanges();
        Transport.send(message);
    }
    /**
     * 目前用於 tag file 的特殊工具, 檢查參數是否存在, 如果存在加到標籤上.
     * 
     * @param attrib 屬性名稱.
     * @param val 傳入內容.
     * @return 組合後的結果.
     */
    public String appendAttrib(String attrib, String val) {
        StringBuffer sb = new StringBuffer();
        if (attrib != null && attrib.trim().length() != 0 && val != null && val.trim().length() != 0) {
            sb.append(" ");
            sb.append(attrib.trim());
            sb.append("=\"");
            sb.append(val.trim());
            sb.append("\"");
        }
        return sb.toString();
    }

    /**
     * 目前用於 tag file 的特殊工具, 檢查參數是否存在, 如果沒有 使用預設值.
     * 
     * @param attrib 屬性名稱.
     * @param val 傳入內容.
     * @param def 預設值.
     * @return 組合後的結果.
     */
    public String appendAttrib(String attrib, String val, String def) {
        StringBuffer sb = new StringBuffer();
        if (attrib != null && attrib.trim().length() != 0) { // 有傳入 attrib
            // 才會加上
            // attribute.
            if (val != null && val.trim().length() != 0) { // 有傳入 val, 就使用 val.
                sb.append(" ");
                sb.append(attrib.trim());
                sb.append("=\"");
                sb.append(val.trim());
                sb.append("\"");
            } else if (def != null && def.trim().length() != 0) { // 如果沒有傳入 val, 但有傳入 def 就使用 def.
                sb.append(" ");
                sb.append(attrib.trim());
                sb.append("=\"");
                sb.append(def.trim());
                sb.append("\"");
            }
        }
        return sb.toString();
    }

    /**
     * 檢查是否符合固定參數接受的值 1 / true / [參數名字].
     * 
     * @param val 檢查值(正確的名稱).
     * @param attrib 傳入值(由jsp傳入的變數).
     * @return
     */
    public boolean checkFixedAttrib(String val, String attrib) {
        return "true".equalsIgnoreCase(attrib) || "1".equalsIgnoreCase(attrib) || (val != null && val.equalsIgnoreCase(attrib));
    }

    public boolean isAuthorized(String sysCode) throws Exception {
        CheckUser cu = new CheckUser(request, this.getHr003aTsn());
        return cu.isAuthorized(sysCode, this.getHrNum());
    }

    /***************************************************************************
     * 取得 Login 時候的 session 相關資料.
     **************************************************************************/
    public String getHrNum() {
        return (String) request.getSession().getAttribute("factno"); // 工號
    }
    
    public String getChName() {
    	return StringHelper.getValue( request.getSession().getAttribute("userId"),(String) request.getSession().getAttribute("chname"));// 中文名稱
    }
    
    public String getDeptName() {
        return (String) request.getSession().getAttribute("deptName"); // 部門名稱
    }

    public String getStaffIf() {
        return (String) request.getSession().getAttribute("staffId"); // 登入帳號
    }

    public String getHr003aTsn() {
        return (String) request.getSession().getAttribute("companyCodeTsn"); // 公司別Tsn
    }

    public String getHr006Tsn() {
        return (String) request.getSession().getAttribute("hr006tsn"); // 帳號權限檔Tsn
    }

    public String getHr003Tsn() {
        return (String) request.getSession().getAttribute("hr003tsn"); // 部門別Tsn
    }

    public String getHr005Tsn() {
        return (String) request.getSession().getAttribute("hr005tsn"); // 人事資料檔Tsn
    }
    
    public String getEmail() {
    	String mail = (String) request.getSession().getAttribute("email");
        return (mail == null || mail.trim().length() == 0) ? "exchgadmin"  : mail; // 郵箱
    }

    public boolean getAuth(String companyCodeTsn, String hr005tsn, Utils utils) throws Exception {
        boolean check = false;
        String sql = "select * from hr..hr005 a,hr..hr006 b,hr..hr003 c where a.tsn=b.hr005tsn and b.defau=1 and b.hr003tsn = c.tsn and c.hr003atsn = '" + companyCodeTsn + "' and a.tsn = '" + hr005tsn + "'";
        ResultSet rs = utils.executeQuery("info3", sql);
        while (rs.next()) {
            check = true;
        }
        return check; // 人事部分權限控製
    }
    /***************************************************************************
     * Database 相關程式.
     **************************************************************************/
    /**
     * 放 Connection 的容器.
     */
    private Map<String, Connection> connPot = new HashMap<String, Connection>();
    /**
     * 放 Statement 的容器.
     */
    private List<PreparedStatement> stmtPot = new ArrayList<PreparedStatement>();
    /**
     * 放 ResultSet 的容器.
     */
    private List<ResultSet> rsPot = new ArrayList<ResultSet>();
    /**
     * 放 SQL語句 的容器.
     */
    private List<String> sqlPot = new ArrayList<String>();
    /**
     * 由 proxool pool 裡面取得連線.  
     * @param serverName
     * @return
     * @throws Exception
     */
    private Connection getConnection(String serverName) throws Exception {
        Connection conn = null;
        SnapshotIF snapshot = null;
        if (serverName.equalsIgnoreCase("PAN")) {
            conn = DriverManager.getConnection("proxool.pan");
            snapshot = ProxoolFacade.getSnapshot("pan", true);
        } else if (serverName.equalsIgnoreCase("fs1")) {
            conn = DriverManager.getConnection("proxool.fs1");
            snapshot = ProxoolFacade.getSnapshot("fs1", true);
        } else {
        	       throw new Exception("- 連線名稱錯誤 : " + serverName);
        }
        
        if(snapshot != null) {
        	int activeCount = snapshot.getActiveConnectionCount();
            if(activeCount == 30) {
            	if(isOfficialSite()) {
            	StringBuffer resultrem = new StringBuffer("");
            		ConnectionInfoIF[] connectionInfos = snapshot.getConnectionInfos();
                    for (int i = 0; i < connectionInfos.length; i++) {
                    	long drillDownConnectionId = 0;
                        ConnectionInfoIF connectionInfo = connectionInfos[i];
                        if (connectionInfo.getStatus() != ConnectionInfoIF.STATUS_NULL) {
                        	if (connectionInfo.getStatus() == ConnectionInfoIF.STATUS_ACTIVE) {
                        		drillDownConnectionId = Long.valueOf(connectionInfo.getId()).longValue();
                        		ConnectionInfoIF drillDownConnection = snapshot.getConnectionInfo(drillDownConnectionId);
                        		String[] sqlCalls = drillDownConnection.getSqlCalls();
                                for (int j = 0; sqlCalls != null && j < sqlCalls.length; j++) {
                                    String sqlCall = sqlCalls[j];
                                    resultrem.append(sqlCall);
                                }
                                resultrem.append(drillDownConnection.getDelegateUrl());
                            }
                        }
                    }
                    this.sendMail("exchgadmin@mail.JMKNIT.com","sime@mail.jmknit.com","景盟jsp網站"+serverName+"主機活動連線已經達到30個,請速查看",resultrem.toString(),Utils.TEXT);
                    //this.sendMail("exchgadmin@mail.JMKNIT.com","jm_mis2@mail.jmknit.com,sun@mail.jmknit.com,yuwei_lin@mail.jmknit.com","景盟jsp網站"+serverName+"主機活動連線已經達到30個,請速查看","",Utils.TEXT);
            	}
            }
            
        }
        
        //conn.setAutoCommit(true);        
        return conn;
    }

    public boolean isOfficialSite() throws Exception {
        boolean result = InetAddress.getLocalHost().getHostAddress().equals("169.169.0.10");
        if(result == false) {
        	result = InetAddress.getLocalHost().getHostAddress().equals("169.169.0.119");
        }
        //正式主機
        //result = true;
        
        return result;
    }
    public boolean isOfficialSiteOut() throws Exception {
        boolean result = InetAddress.getLocalHost().getHostAddress().equals("169.169.0.19");
        //正式主機
        //result = true;
        
        return result;
    }
    public String getTable(ServletContext application, String databaseName, String tableName) throws Exception {
        String result = null;
        try {
            String symbol = "..";
            // 由  application 取得連線 server名稱.
            result = (String) application.getAttribute(databaseName + symbol + tableName);
            // 如果 application 裡面沒有這個table, 就從 Database 再讀取一次.
            if (result == null) {
                String sql = "select * from sys..sys015";
                boolean official = this.isOfficialSite();
                ResultSet rs = this.executeQuery("info", sql); // 以 info上面的為準.
                while (rs.next()) {
                    String connId = rs.getString("databaseName") + symbol + rs.getString("tableName");
                    if (official || this.isOfficialSite()) {
                        application.setAttribute(connId, rs.getString("officialConn"));
                    } else {
                        application.setAttribute(connId, rs.getString("testConn"));
                    }
                }
                // 重新取得一次.
                result = (String) application.getAttribute(databaseName + symbol + tableName);
            }
        } catch (Exception ex) {
            System.out.println("- Utils.getTable() 發生錯誤 !!");
            this.cleanUp();
            throw ex;
        }
        return result;
    }
    
    /**
     * 查詢 sql 語句.
     * @param serverName
     * @param sql
     * @return
     */
    public ResultSet executePagingQuery(String serverName, String sql) throws Exception {
        sqlPot.add(sql); // 放入 sql.
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            // 檢查是否有連線存在 conns, 如果沒有, 建一個放進去. 
            if ((conn = (Connection) connPot.get(serverName)) == null) {
                conn = getConnection(serverName);
                connPot.put(serverName, conn);
            }
            conn.setAutoCommit(this.autoCommit);
            // 取得 statement.
            //stmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            stmt = conn.prepareStatement(sql);
            stmtPot.add(stmt);
            // 取得 rs.
            rs = stmt.executeQuery();
            if(stmt.getMoreResults()){
            	rs = stmt.getResultSet();
            }
            rsPot.add(rs);
        } catch (Exception e) {
            // rollback();
            System.out.println("- Utils.executeQuery() 發生錯誤 !!");
            System.out.println("- Server Name : " + serverName);
            System.out.println("- SQL : " + sql);
            this.cleanUp();
            throw e;
        }
        return rs;
    }
    

    /**
     * 查詢 sql 語句.
     * @param serverName
     * @param sql
     * @return
     */
    public ResultSet executeQuery(String serverName, String sql) throws Exception {
        sqlPot.add(sql); // 放入 sql.
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            // 檢查是否有連線存在 conns, 如果沒有, 建一個放進去. 
            if ((conn = (Connection) connPot.get(serverName)) == null) {
                conn = getConnection(serverName);
                connPot.put(serverName, conn);
            }
            conn.setAutoCommit(this.autoCommit);
            // 取得 statement.
            //stmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            stmt = conn.prepareStatement(sql);
            stmtPot.add(stmt);
            // 取得 rs.
            rs = stmt.executeQuery();
            
            rsPot.add(rs);
        } catch (Exception e) {
            // rollback();
            System.out.println("- Utils.executeQuery() 發生錯誤 !!");
            System.out.println("- Server Name : " + serverName);
            System.out.println("- SQL : " + sql);
            this.cleanUp();
            throw e;
        }
        return rs;
    }

    /**
     * 執行 sql 語句.
     * @param serverName
     * @param sql
     * @return
     */
    public int executeUpdate(String serverName, String sql) throws Exception {
        sqlPot.add(sql); // 放入 sql.
        Connection conn = null;
        PreparedStatement stmt = null;
        int result = 0;
        try {
            // 檢查是否有連線存在 conns, 如果沒有, 建一個放進去.
            if ((conn = (Connection) connPot.get(serverName)) == null) {
                conn = getConnection(serverName);
                connPot.put(serverName, conn);
            }
            conn.setAutoCommit(this.autoCommit);
            // 取得 statement.
            stmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            stmtPot.add(stmt);
            // 執行.
            result = stmt.executeUpdate();
        } catch (Exception e) {
            // rollback();
            System.out.println("===== Utils.executeUpdate() 發生錯誤 !!");
            System.out.println("- Server Name : " + serverName);
            System.out.println("- SQL : " + sql);
            this.cleanUp();
            throw e;
        }
        return result;
    }

    /**
     * rollback.
     */
    private void rollback() {
        try {
            if (connPot != null) {
                for (Connection conn : connPot.values()) {
                    if (conn != null && !conn.isClosed()) {
                        conn.rollback();
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("====== Utils.rollback() 發生錯誤 !!");
            for (String str : sqlPot) {
                System.out.println("- " + str);
            }
            e.printStackTrace();
        }
    }


    private void setAutoCommit(boolean boo) throws Exception {
        try {
            if (connPot != null) {
                for (Connection conn : connPot.values()) {
                    if (conn != null && !conn.isClosed()) {
                        conn.setAutoCommit(boo);
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("====== Utils.setAutoCommit() 發生錯誤 !!");
            throw e;
        }
    }
    
    private boolean autoCommit = true;
    public void setTransaction() throws Exception {
    	this.autoCommit = false;
    }
    
    /**
     * commit.
     * @throws Exception
     */
    public void commit() throws Exception {
        try {
            if (connPot != null) {
                for (Connection conn : connPot.values()) {
                    if (conn != null && !conn.isClosed()) {
                        conn.commit();
                    }
                }
            }
            this.setAutoCommit(true);
        } catch (Exception e) {
            System.out.println("====== Utils.commit() 發生錯誤 !!");
            throw e;
        }
    }

    /**
     * 清除 rs, stmt, conn 的資料庫相關物件.
     */
    public void cleanUp() {
        try {
            // commit();
            // 清除rs.
            if (rsPot != null) {
                for (ResultSet rs : rsPot) {
                    if (rs != null) {
                        rs.close();
                    }
                }
                rsPot.clear();
            }
            // 清除stmt.
            if (stmtPot != null) {
                for (PreparedStatement stmt : stmtPot) {
                    if (stmt != null) {
                        stmt.close();
                    }
                }
                stmtPot.clear();
            }
            // 清除連線.
            if (connPot != null) {
                for (Connection conn : connPot.values()) {
                    if (conn != null && !conn.isClosed()) {
                        conn.close();
                    }
                }
                connPot.clear();
            }
        } catch (Exception e) {
            // rollback();
            System.out.println("\n- " + formatDateTime(new Date()));
            System.out.println("- Utils.cleanUp() 發生錯誤 !!");
            for (String str : sqlPot) {
                System.out.println("- " + str);
            }
            e.printStackTrace();
        }
    }
    /***************************************************************************
     * Database 的 PreparedStatement.
     **************************************************************************/
    /**
     * 使用 PreparedStatement 的暫存變數.
     */
    private PreparedStatement stmt = null;

    /**
     * 設定 PreparedStatement.
     * @param serverName
     * @param sql
     */
    public void prepareStatement(String serverName, String sql) throws Exception {
        sqlPot.add(sql); // 放入 sql.
        Connection conn = null;
        try {
            // 檢查是否有連線存在 conns, 如果沒有, 建一個放進去.
            if ((conn = (Connection) connPot.get(serverName)) == null) {
                conn = getConnection(serverName);
                connPot.put(serverName, conn);
            }
            conn.setAutoCommit(this.autoCommit);
            // 取得 statement.
            stmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            stmtPot.add(stmt);
        } catch (Exception e) {
            // rollback();
            System.out.println("===== Utils.prepareStatement() 發生錯誤 !!");
            this.cleanUp();
            throw e;
        }
    }

    /**
     * 將 String 放入 PreparedStatement.
     * @param i
     * @param str
     */
    public void setString(int i, String str) throws Exception {
        try {
            stmt.setString(i, str);
        } catch (Exception e) {
            // rollback();
            System.out.println("===== Utils.setString() 發生錯誤 !!");
            this.cleanUp();
            throw e;
        }
    }

    /**
     * 將 Int 放入 PreparedStatement.
     * @param i
     * @param intParam
     * 
     */
    public void setInt(int i, int intParam) throws Exception {
        try {
            stmt.setInt(i, intParam);
        } catch (Exception e) {
            // rollback();
            System.out.println("===== Utils.setInt() 發生錯誤 !!");
            this.cleanUp();
            throw e;
        }
    }

    public void setDouble(int i, double doubleParam) throws Exception {
        try {
            stmt.setDouble(i, doubleParam);
        } catch (Exception e) {
            // rollback();
            System.out.println("===== Utils.setDouble() 發生錯誤 !!");
            this.cleanUp();
            throw e;
        }
    }

     /**
     * 將 二進位資料 放入 PreparedStatement.
     * @param i
     * @param stream
     * @param length
     * @deprecated 此方法作廢.
     */
    public void setBinaryStream(int i, InputStream stream, int length) throws Exception {
        try {
            stmt.setBinaryStream(i, stream, length);
        } catch (Exception e) {
            // rollback();
            System.out.println("===== Utils.setBinaryStream() 發生錯誤 !!");
            this.cleanUp();
            throw e;
        }
    }
    
    public void setBinaryStream(int i, byte[] data) throws Exception {
        try {
        	ByteArrayInputStream input = new ByteArrayInputStream(new byte[0]);
			if(data != null){
				input = new ByteArrayInputStream(data);
			}
            stmt.setBinaryStream(i, input, input.available());
        } catch (Exception e) {
            // rollback();
            System.out.println("===== Utils.setBinaryStream() 發生錯誤 !!");
            this.cleanUp();
            throw e;
        }
    }
    
    
    /**
     * 執行.
     * @return
     */
    public int executeUpdate() throws Exception {
        int result = 0;
        try {
            result = stmt.executeUpdate();
            
        } catch (Exception e) {
            // rollback();
            System.out.println("===== Utils.executeUpdate() 發生錯誤 !!");
            this.cleanUp();
            throw e;
        }
        return result;
    }

    /**
     * 查詢.
     * @return
     */
    public ResultSet executeQuery() throws Exception {
        ResultSet rs = null;
        try {
            rs = stmt.executeQuery();
            rsPot.add(rs);
        } catch (Exception e) {
            // rollback();
            System.out.println("===== Utils.executeQuery() 發生錯誤 !!");
            this.cleanUp();
            throw e;
        }
        return rs;
    }

    /***************************************************************************
     * 處理分頁查詢.
     **************************************************************************/
    /**
     * 畫面上要分頁, 使用的查詢方式.
     */
    public ResultSet executePagingQuery(String serverName, String sql, String uniqueColumn) throws Exception {
        int page = this.getIntParam("_page");
        //System.out.println(this.parsePagingSql(sql, page, uniqueColumn));
        return this.executeQuery(serverName, this.parsePagingSql(sql, page, uniqueColumn));
    }

    
    /**
     * utils:page 需要查詢的相關資料. 
     */
    public int[] getPagingData(String serverName, String str) throws Exception {
        int[] result = new int[2];
        String[] pagingSql = this.splitPagingSql(str);
        String num = pagingSql[0];
        String showColumn = pagingSql[1];
        String fromWhere = pagingSql[2];
        String groupBy = pagingSql[3];
        StringBuffer sb = new StringBuffer();
        // 查詢句裡面有沒有 group by 做法不太一樣.
        if (groupBy.length() != 0) {
            sb.append("select count(*) as total from (select ").append(showColumn).append(" from ").append(fromWhere).append(" group by ").append(groupBy).append(") as totalRecordsForPaging");
        } else {
            sb.append("select count(*) as total from ").append(fromWhere);
        }
        ResultSet rs = this.executeQuery(serverName, sb.toString());
        rs.next();
        result[0] = rs.getInt(1); // 取的總筆數
        result[1] = Integer.parseInt(num); // 取得一頁有幾個筆資料
        return result;
    }

    /**
     * 重新湊出分頁SQL語句.
     */
    private String parsePagingSql(String str, int page, String uniqueColumn) {
        String[] pagingSql = this.splitPagingSql(str);
        String num = pagingSql[0];
        String showColumn = pagingSql[1];
        String fromWhere = pagingSql[2];
        String groupBy = pagingSql[3];
        String orderBy = pagingSql[4];
        page = (page < 1) ? 1 : page; // page 最小 = 1.
        StringBuffer sb = new StringBuffer();
        sb.append("select top ").append(num).append(" ").append(showColumn).append(" from ").append(fromWhere);
        if (fromWhere.contains("where")) { // 查詢句 有沒有 where 處理方式不一樣.
            sb.append(" and ");
        } else {
            sb.append(" where ");
        }
        sb.append(" not ").append(uniqueColumn).append(" in (select top ").append(Integer.parseInt(num) * (page - 1)).append(" ").append(uniqueColumn).append(" from ").append(fromWhere);
        if (groupBy.length() != 0) { // 查詢句 有沒有 group by 處理方式不一樣.
            sb.append(" group by ").append(groupBy);
        }
        if (orderBy.length() != 0) { // 查詢句 有沒有 order by 處理方式不一樣.
            sb.append(" order by ").append(orderBy);
        }
        sb.append(" ) ");
        if (groupBy.length() != 0) { // 查詢句 有沒有 group by 處理方式不一樣.
            sb.append(" group by ").append(groupBy);
        }
        if (orderBy.length() != 0) { // 查詢句 有沒有 order by 處理方式不一樣.
            sb.append(" order by ").append(orderBy);
        }
        return sb.toString();
    }

    /**
     * 拆解查詢SQL. 
     */
    private String[] splitPagingSql(String str) {
        String[] result = { "30", "", "", "", "" }; // {預設顯示筆數, showColumn, fromWhere, groupBy, orderBy}
        // 1. 資料筆數 = top 的筆數, 預設 30 筆. 
        String sql = str.toLowerCase().replaceFirst("select", "").replaceAll("\\(", " \\( ").replaceAll("\\)", " \\) ").trim();
        if (sql.startsWith("top")) { // 有 top 就取得數字. 
            sql = sql.replaceFirst("top", "").trim();
            result[0] = sql.split(" ")[0];
            sql = sql.replaceFirst(result[0], "").trim();
        }
        // 2. 要顯示的 column : 第一個不在()之內 的from 之前的字串都是.
        String[] array = this.splitIgnoreSpecial(sql, "from");
        result[1] = array[0];
        sql = array[1];
        array = this.splitIgnoreSpecial(sql, "group");
        if (array[1].length() == 0) { // 此 sql 沒有包含 group by
            array = this.splitIgnoreSpecial(sql, "order");
            result[2] = array[0];
            result[4] = array[1].replaceFirst("by", "").trim();
        } else { // 有 group by
            result[2] = array[0];
            sql = array[1].replaceFirst("by", "").trim();
            array = this.splitIgnoreSpecial(sql, "order");
            result[3] = array[0];
            result[4] = array[1].replaceFirst("by", "").trim();
        }
        if (result[4].length() == 0) {
            System.out.print("- 分頁查詢沒有order by資料 : ");
            System.out.println(str);
        }
        return result;
    }

    /**
     * 拆解SQL需要用的到一個方法.
     */
    private String[] splitIgnoreSpecial(String str, String split) {
        split = new StringBuffer().append(" ").append(split).append(" ").toString();
        // 找到第一個 split 分隔字, 且不包含在 ( ) 之內.  
        String[] result = new String[2];
        int index = 0;
        int len = str.length();
        while (true) {
            index = str.indexOf(split, index);
            index = (index == -1) ? len : index;
            result[0] = str.substring(0, index).trim();
            int next = (index + split.length() > len) ? len : index + split.length();
            result[1] = str.substring(next, len).trim();
            // 左右兩邊的   ' 要成對的, 且 ()個數必須相同.
            if (result[0].replaceAll("[^\\(]", "").length() == result[0].replaceAll("[^\\)]", "").length() && result[1].replaceAll("[^\\(]", "").length() == result[1].replaceAll("[^\\)]", "").length() && result[0].replaceAll("[^']", "").length() % 2 == 0 && result[1].replaceAll("[^']", "").length() % 2 == 0) {
                break;
            } else {
                index++;
            }
        }
        return result;
    }

    /**
     * 用於取得網頁查詢的參數. 
     */
    public String toQueryString() {
        StringBuffer sb = new StringBuffer();
        Enumeration names = request.getParameterNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
            String value = this.getStringParam(name);
            if (value.length() != 0) {
                sb.append((sb.length() == 0) ? "" : "&").append(name).append("=").append(this.unescape(value));
            }
        }
        return sb.toString();
    }
    
    
    //mouse 寫的數字格式檢查
    public boolean isNumValid(String arg, int length, double Min, double Max, boolean isApproximate) {
        boolean rs = true;
        String tp1 = arg;
        arg = tp1.replaceAll("\\d{1,}", "true");
        if (!arg.equals("true")) {
            boolean tp2 = false;
            for (int i = 1; i <= length; i++) {
                if (isApproximate) {
                    arg = tp1.replaceAll("\\d{1,}\\.\\d{1,}", "true");
                } else {
                    arg = tp1.replaceAll("\\d{1,}\\.\\d{" + i + "}", "true");
                }
                if (arg.equals("true")) {
                    tp2 = true;
                }
            }
            if (!tp2) {
                rs = false;
            }
        }
        if (Min != Max && rs) {
            if (Double.parseDouble(tp1) > Max || Double.parseDouble(tp1) < Min) {
                rs = false;
            }
        }
        return rs;
    }

    /**
     * 例外處理記錄.
     */
    public void recordException(Exception ex) {
        // 時間.
        System.out.println("===== Time : " + this.formatDateTime(Calendar.getInstance().getTime()) + " ================================================");
        // Remote IP.
        System.out.println("- Remote IP : " + request.getRemoteAddr());
        // RUL.
        System.out.println("- URL : " + request.getRequestURI() + "?" + request.getQueryString());
        // session data.
        HttpSession sess = request.getSession();
        System.out.println("- companyCodeTsn[" + sess.getAttribute("companyCodeTsn") + "], hr006tsn[" + sess.getAttribute("hr006tsn") + "], staffId[" + sess.getAttribute("staffId") + "], hrnum[" + sess.getAttribute("factno") + "], chname[" + sess.getAttribute("userId") + "], hr003tsn[" + sess.getAttribute("hr003tsn") + "], hr005tsn[" + sess.getAttribute("hr005tsn") + "], user_no["+sess.getAttribute("user_no")+"]");
        System.out.println("- Exception : " + ex.getMessage());
    }
    
    /**
     * @param char 
     * @return boolean
     */
    private boolean isChinese(char c) {
		Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
		if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
				|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
				|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
				|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
				|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
				|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
			return true;
		}
		return false;
	}

	/**
	 * @param String
	 * @return boolean
	 */
	public boolean isChinese(String strName) {
		char[] ch = strName.toCharArray();
		for (int i = 0; i < ch.length; i++) {
			char c = ch[i];
			if (isChinese(c)) {
				return true;
			}
		}
		return false;
	}
    
    
	public String getCookieValue(Cookie[] cookies,String cookieName,String defaultValue) {
		//Cookie[] cookies = request.getCookies();
		for(int i=0; i<cookies.length; i++) {
			//System.out.println(cookies[i]);
			Cookie cookie = cookies[i];
			if (cookieName.equals(cookie.getName()))
			return(cookie.getValue());
		}
		return(defaultValue);
	}
	
	public String appendValidCode(String str) {
		int count = 0;
		int index = 1;
		String result = str.replaceAll("[^\\d{1,}|^a-zA-Z]", "").toUpperCase();// 正則表達式,將非字母非數字移除
		for (int i = result.length() - 1; i >= 0; i--) {
			char x = result.charAt(i);
			if (Character.isLetter(x)) {
				count += ((int) x - 64) * index; // 將字母A-Z轉變成1-26的數字
			} else {
				count += Integer.parseInt(String.valueOf(x)) * index;
			}
			index++;
		}
		int validCode = (10 - count % 10) % 10; // 得到驗證碼
		return str + validCode;
	}
	public String charPYStr(){
        return "啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙坝霸罢爸白柏百摆佰败拜稗斑班搬扳般颁板版扮拌伴瓣半办绊邦帮梆榜膀绑棒磅蚌镑傍谤苞胞包褒剥薄雹保堡饱宝抱报暴豹鲍爆杯碑悲卑北辈背贝钡倍狈备惫焙被奔苯本笨崩绷甭泵蹦迸逼鼻比鄙笔彼碧蓖蔽毕毙毖币庇痹闭敝弊必辟壁臂避陛鞭边编贬扁便变卞辨辩辫遍标彪膘表鳖憋别瘪彬斌濒滨宾摈兵冰柄丙秉饼炳病并玻菠播拨钵波博勃搏铂箔伯帛舶脖膊渤泊驳捕卜哺补埠不布步簿部怖擦猜裁材才财睬踩采彩菜蔡餐参蚕残惭惨灿苍舱仓沧藏操糙槽曹草厕策侧册测层蹭插叉茬茶查碴搽察岔差诧拆柴豺搀掺蝉馋谗缠铲产阐颤昌猖场尝常长偿肠厂敞畅唱倡超抄钞朝嘲潮巢吵炒车扯撤掣彻澈郴臣辰尘晨忱沉陈趁衬撑称城橙成呈乘程惩澄诚承逞骋秤吃痴持匙池迟弛驰耻齿侈尺赤翅斥炽充冲虫崇宠抽酬畴踌稠愁筹仇绸瞅丑臭初出橱厨躇锄雏滁除楚础储矗搐触处揣川穿椽传船喘串疮窗幢床闯创吹炊捶锤垂春椿醇唇淳纯蠢戳绰疵茨磁雌辞慈瓷词此刺赐次聪葱囱匆从丛凑粗醋簇促蹿篡窜摧崔催脆瘁粹淬翠村存寸磋撮搓措挫错搭达答瘩打大呆歹傣戴带殆代贷袋待逮怠耽担丹单郸掸胆旦氮但惮淡诞弹蛋当挡党荡档刀捣蹈倒岛祷导到稻悼道盗德得的蹬灯登等瞪凳邓堤低滴迪敌笛狄涤翟嫡抵底地蒂第帝弟递缔颠掂滇碘点典靛垫电佃甸店惦奠淀殿碉叼雕凋刁掉吊钓调跌爹碟蝶迭谍叠丁盯叮钉顶鼎锭定订丢东冬董懂动栋侗恫冻洞兜抖斗陡豆逗痘都督毒犊独读堵睹赌杜镀肚度渡妒端短锻段断缎堆兑队对墩吨蹲敦顿囤钝盾遁掇哆多夺垛躲朵跺舵剁惰堕蛾峨鹅俄额讹娥恶厄扼遏鄂饿恩而儿耳尔饵洱二贰发罚筏伐乏阀法珐藩帆番翻樊矾钒繁凡烦反返范贩犯饭泛坊芳方肪房防妨仿访纺放菲非啡飞肥匪诽吠肺废沸费芬酚吩氛分纷坟焚汾粉奋份忿愤粪丰封枫蜂峰锋风疯烽逢冯缝讽奉凤佛否夫敷肤孵扶拂辐幅氟符伏俘服浮涪福袱弗甫抚辅俯釜斧脯腑府腐赴副覆赋复傅付阜父腹负富讣附妇缚咐噶嘎该改概钙盖溉干甘杆柑竿肝赶感秆敢赣冈刚钢缸肛纲岗港杠篙皋高膏羔糕搞镐稿告哥歌搁戈鸽胳疙割革葛格蛤阁隔铬个各给根跟耕更庚羹埂耿梗工攻功恭龚供躬公宫弓巩汞拱贡共钩勾沟苟狗垢构购够辜菇咕箍估沽孤姑鼓古蛊骨谷股故顾固雇刮瓜剐寡挂褂乖拐怪棺关官冠观管馆罐惯灌贯光广逛瑰规圭硅归龟闺轨鬼诡癸桂柜跪贵刽辊滚棍锅郭国果裹过哈骸孩海氦亥害骇酣憨邯韩含涵寒函喊罕翰撼捍旱憾悍焊汗汉夯杭航壕嚎豪毫郝好耗号浩呵喝荷菏核禾和何合盒貉阂河涸赫褐鹤贺嘿黑痕很狠恨哼亨横衡恒轰哄烘虹鸿洪宏弘红喉侯猴吼厚候后呼乎忽瑚壶葫胡蝴狐糊湖弧虎唬护互沪户花哗华猾滑画划化话槐徊怀淮坏欢环桓还缓换患唤痪豢焕涣宦幻荒慌黄磺蝗簧皇凰惶煌晃幌恍谎灰挥辉徽恢蛔回毁悔慧卉惠晦贿秽会烩汇讳诲绘荤昏婚魂浑混豁活伙火获或惑霍货祸击圾基机畸稽积箕肌饥迹激讥鸡姬绩缉吉极棘辑籍集及急疾汲即嫉级挤几脊己蓟技冀季伎祭剂悸济寄寂计记既忌际妓继纪嘉枷夹佳家加荚颊贾甲钾假稼价架驾嫁歼监坚尖笺间煎兼肩艰奸缄茧检柬碱硷拣捡简俭剪减荐槛鉴践贱见键箭件健舰剑饯渐溅涧建僵姜将浆江疆蒋桨奖讲匠酱降蕉椒礁焦胶交郊浇骄娇嚼搅铰矫侥脚狡角饺缴绞剿教酵轿较叫窖揭接皆秸街阶截劫节茎睛晶鲸京惊精粳经井警景颈静境敬镜径痉靖竟竞净炯窘揪究纠玖韭久灸九酒厩救旧臼舅咎就疚鞠拘狙疽居驹菊局咀矩举沮聚拒据巨具距踞锯俱句惧炬剧捐鹃娟倦眷卷绢撅攫抉掘倔爵桔杰捷睫竭洁结解姐戒藉芥界借介疥诫届巾筋斤金今津襟紧锦仅谨进靳晋禁近烬浸尽劲荆兢觉决诀绝均菌钧军君峻俊竣浚郡骏喀咖卡咯开揩楷凯慨刊堪勘坎砍看康慷糠扛抗亢炕考拷烤靠坷苛柯棵磕颗科壳咳可渴克刻客课肯啃垦恳坑吭空恐孔控抠口扣寇枯哭窟苦酷库裤夸垮挎跨胯块筷侩快宽款匡筐狂框矿眶旷况亏盔岿窥葵奎魁傀馈愧溃坤昆捆困括扩廓阔垃拉喇蜡腊辣啦莱来赖蓝婪栏拦篮阑兰澜谰揽览懒缆烂滥琅榔狼廊郎朗浪捞劳牢老佬姥酪烙涝勒乐雷镭蕾磊累儡垒擂肋类泪棱楞冷厘梨犁黎篱狸离漓理李里鲤礼莉荔吏栗丽厉励砾历利傈例俐痢立粒沥隶力璃哩俩联莲连镰廉怜涟帘敛脸链恋炼练粮凉梁粱良两辆量晾亮谅撩聊僚疗燎寥辽潦了撂镣廖料列裂烈劣猎琳林磷霖临邻鳞淋凛赁吝拎玲菱零龄铃伶羚凌灵陵岭领另令溜琉榴硫馏留刘瘤流柳六龙聋咙笼窿隆垄拢陇楼娄搂篓漏陋芦卢颅庐炉掳卤虏鲁麓碌露路赂鹿潞禄录陆戮驴吕铝侣旅履屡缕虑氯律率滤绿峦挛孪滦卵乱掠略抡轮伦仑沦纶论萝螺罗逻锣箩骡裸落洛骆络妈麻玛码蚂马骂嘛吗埋买麦卖迈脉瞒馒蛮满蔓曼慢漫谩芒茫盲氓忙莽猫茅锚毛矛铆卯茂冒帽貌贸么玫枚梅酶霉煤没眉媒镁每美昧寐妹媚门闷们萌蒙檬盟锰猛梦孟眯醚靡糜迷谜弥米秘觅泌蜜密幂棉眠绵冕免勉娩缅面苗描瞄藐秒渺庙妙蔑灭民抿皿敏悯闽明螟鸣铭名命谬摸摹蘑模膜磨摩魔抹末莫墨默沫漠寞陌谋牟某拇牡亩姆母墓暮幕募慕木目睦牧穆拿哪呐钠那娜纳氖乃奶耐奈南男难囊挠脑恼闹淖呢馁内嫩能妮霓倪泥尼拟你匿腻逆溺蔫拈年碾撵捻念娘酿鸟尿捏聂孽啮镊镍涅您柠狞凝宁拧泞牛扭钮纽脓浓农弄奴努怒女暖虐疟挪懦糯诺哦欧鸥殴藕呕偶沤啪趴爬帕怕琶拍排牌徘湃派攀潘盘磐盼畔判叛乓庞旁耪胖抛咆刨炮袍跑泡呸胚培裴赔陪配佩沛喷盆砰抨烹澎彭蓬棚硼篷膨朋鹏捧碰坯砒霹批披劈琵毗啤脾疲皮匹痞僻屁譬篇偏片骗飘漂瓢票撇瞥拼频贫品聘乒坪苹萍平凭瓶评屏坡泼颇婆破魄迫粕剖扑铺仆莆葡菩蒲埔朴圃普浦谱曝瀑期欺栖戚妻七凄漆柒沏其棋奇歧畦崎脐齐旗祈祁骑起岂乞企启契砌器气迄弃汽泣讫掐洽牵扦钎铅千迁签仟谦乾黔钱钳前潜遣浅谴堑嵌欠歉枪呛腔羌墙蔷强抢橇锹敲悄桥瞧乔侨巧鞘撬翘峭俏窍切茄且怯窃钦侵亲秦琴勤芹擒禽寝沁青轻氢倾卿清擎晴氰情顷请庆琼穷秋丘邱球求囚酋泅趋区蛆曲躯屈驱渠取娶龋趣去圈颧权醛泉全痊拳犬券劝缺炔瘸却鹊榷确雀裙群然燃冉染瓤壤攘嚷让饶扰绕惹热壬仁人忍韧任认刃妊纫扔仍日戎茸蓉荣融熔溶容绒冗揉柔肉茹蠕儒孺如辱乳汝入褥软阮蕊瑞锐闰润若弱撒洒萨腮鳃塞赛三叁伞散桑嗓丧搔骚扫嫂瑟色涩森僧莎砂杀刹沙纱傻啥煞筛晒珊苫杉山删煽衫闪陕擅赡膳善汕扇缮墒伤商赏晌上尚裳梢捎稍烧芍勺韶少哨邵绍奢赊蛇舌舍赦摄射慑涉社设砷申呻伸身深娠绅神沈审婶甚肾慎渗声生甥牲升绳省盛剩胜圣师失狮施湿诗尸虱十石拾时什食蚀实识史矢使屎驶始式示士世柿事拭誓逝势是嗜噬适仕侍释饰氏市恃室视试收手首守寿授售受瘦兽蔬枢梳殊抒输叔舒淑疏书赎孰熟薯暑曙署蜀黍鼠属术述树束戍竖墅庶数漱恕刷耍摔衰甩帅栓拴霜双爽谁水睡税吮瞬顺舜说硕朔烁斯撕嘶思私司丝死肆寺嗣四伺似饲巳松耸怂颂送宋讼诵搜艘擞嗽苏酥俗素速粟僳塑溯宿诉肃酸蒜算虽隋随绥髓碎岁穗遂隧祟孙损笋蓑梭唆缩琐索锁所塌他它她塔獭挞蹋踏胎苔抬台泰酞太态汰坍摊贪瘫滩坛檀痰潭谭谈坦毯袒碳探叹炭汤塘搪堂棠膛唐糖倘躺淌趟烫掏涛滔绦萄桃逃淘陶讨套特藤腾疼誊梯剔踢锑提题蹄啼体替嚏惕涕剃屉天添填田甜恬舔腆挑条迢眺跳贴铁帖厅听烃汀廷停亭庭挺艇通桐酮瞳同铜彤童桶捅筒统痛偷投头透凸秃突图徒途涂屠土吐兔湍团推颓腿蜕褪退吞屯臀拖托脱鸵陀驮驼椭妥拓唾挖哇蛙洼娃瓦袜歪外豌弯湾玩顽丸烷完碗挽晚皖惋宛婉万腕汪王亡枉网往旺望忘妄威巍微危韦违桅围唯惟为潍维苇萎委伟伪尾纬未蔚味畏胃喂魏位渭谓尉慰卫瘟温蚊文闻纹吻稳紊问嗡翁瓮挝蜗涡窝我斡卧握沃巫呜钨乌污诬屋无芜梧吾吴毋武五捂午舞伍侮坞戊雾晤物勿务悟误昔熙析西硒矽晰嘻吸锡牺稀息希悉膝夕惜熄烯溪汐犀檄袭席习媳喜铣洗系隙戏细瞎虾匣霞辖暇峡侠狭下厦夏吓掀锨先仙鲜纤咸贤衔舷闲涎弦嫌显险现献县腺馅羡宪陷限线相厢镶香箱襄湘乡翔祥详想响享项巷橡像向象萧硝霄削哮嚣销消宵淆晓小孝校肖啸笑效楔些歇蝎鞋协挟携邪斜胁谐写械卸蟹懈泄泻谢屑薪芯锌欣辛新忻心信衅星腥猩惺兴刑型形邢行醒幸杏性姓兄凶胸匈汹雄熊休修羞朽嗅锈秀袖绣墟戌需虚嘘须徐许蓄酗叙旭序畜恤絮婿绪续轩喧宣悬旋玄选癣眩绚靴薛学穴雪血勋熏循旬询寻驯巡殉汛训讯逊迅压押鸦鸭呀丫芽牙蚜崖衙涯雅哑亚讶焉咽阉烟淹盐严研蜒岩延言颜阎炎沿奄掩眼衍演艳堰燕厌砚雁唁彦焰宴谚验殃央鸯秧杨扬佯疡羊洋阳氧仰痒养样漾邀腰妖瑶摇尧遥窑谣姚咬舀药要耀椰噎耶爷野冶也页掖业叶曳腋夜液一壹医揖铱依伊衣颐夷遗移仪胰疑沂宜姨彝椅蚁倚已乙矣以艺抑易邑屹亿役臆逸肄疫亦裔意毅忆义益溢诣议谊译异翼翌绎茵荫因殷音阴姻吟银淫寅饮尹引隐印英樱婴鹰应缨莹萤营荧蝇迎赢盈影颖硬映哟拥佣臃痈庸雍踊蛹咏泳涌永恿勇用幽优悠忧尤由邮铀犹油游酉有友右佑釉诱又幼迂淤于盂榆虞愚舆余俞逾鱼愉渝渔隅予娱雨与屿禹宇语羽玉域芋郁吁遇喻峪御愈欲狱育誉浴寓裕预豫驭鸳渊冤元垣袁原援辕园员圆猿源缘远苑愿怨院曰约越跃钥岳粤月悦阅耘云郧匀陨允运蕴酝晕韵孕匝砸杂栽哉灾宰载再在咱攒暂赞赃脏葬遭糟凿藻枣早澡蚤躁噪造皂灶燥责择则泽贼怎增憎曾赠扎喳渣札轧铡闸眨栅榨咋乍炸诈摘斋宅窄债寨瞻毡詹粘沾盏斩辗崭展蘸栈占战站湛绽樟章彰漳张掌涨杖丈帐账仗胀瘴障招昭找沼赵照罩兆肇召遮折哲蛰辙者锗蔗这浙珍斟真甄砧臻贞针侦枕疹诊震振镇阵蒸挣睁征狰争怔整拯正政帧症郑证芝枝支吱蜘知肢脂汁之织职直植殖执值侄址指止趾只旨纸志挚掷至致置帜峙制智秩稚质炙痔滞治窒中盅忠钟衷终种肿重仲众舟周州洲诌粥轴肘帚咒皱宙昼骤珠株蛛朱猪诸诛逐竹烛煮拄瞩嘱主著柱助蛀贮铸筑住注祝驻抓爪拽专砖转撰赚篆桩庄装妆撞壮状椎锥追赘坠缀谆准捉拙卓桌琢茁酌啄着灼浊兹咨资姿滋淄孜紫仔籽滓子自渍字鬃棕踪宗综总纵邹走奏揍租足卒族祖诅阻组钻纂嘴醉最罪尊遵昨左佐柞做作坐座";
    }

    public String ftPYStr(){
        return "啊阿埃挨哎唉哀皚癌藹矮艾礙愛隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翺襖傲奧懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙壩霸罷爸白柏百擺佰敗拜稗斑班搬扳般頒板版扮拌伴瓣半辦絆邦幫梆榜膀綁棒磅蚌鎊傍謗苞胞包褒剝薄雹保堡飽寶抱報暴豹鮑爆杯碑悲卑北輩背貝鋇倍狽備憊焙被奔苯本笨崩繃甭泵蹦迸逼鼻比鄙筆彼碧蓖蔽畢斃毖幣庇痹閉敝弊必辟壁臂避陛鞭邊編貶扁便變卞辨辯辮遍標彪膘表鼈憋別癟彬斌瀕濱賓擯兵冰柄丙秉餅炳病並玻菠播撥缽波博勃搏鉑箔伯帛舶脖膊渤泊駁捕蔔哺補埠不布步簿部怖擦猜裁材才財睬踩采彩菜蔡餐參蠶殘慚慘燦蒼艙倉滄藏操糙槽曹草廁策側冊測層蹭插叉茬茶查碴搽察岔差詫拆柴豺攙摻蟬饞讒纏鏟産闡顫昌猖場嘗常長償腸廠敞暢唱倡超抄鈔朝嘲潮巢吵炒車扯撤掣徹澈郴臣辰塵晨忱沈陳趁襯撐稱城橙成呈乘程懲澄誠承逞騁秤吃癡持匙池遲弛馳恥齒侈尺赤翅斥熾充沖蟲崇寵抽酬疇躊稠愁籌仇綢瞅醜臭初出櫥廚躇鋤雛滁除楚礎儲矗搐觸處揣川穿椽傳船喘串瘡窗幢床闖創吹炊捶錘垂春椿醇唇淳純蠢戳綽疵茨磁雌辭慈瓷詞此刺賜次聰蔥囪匆從叢湊粗醋簇促躥篡竄摧崔催脆瘁粹淬翠村存寸磋撮搓措挫錯搭達答瘩打大呆歹傣戴帶殆代貸袋待逮怠耽擔丹單鄲撣膽旦氮但憚淡誕彈蛋當擋黨蕩檔刀搗蹈倒島禱導到稻悼道盜德得的蹬燈登等瞪凳鄧堤低滴迪敵笛狄滌翟嫡抵底地蒂第帝弟遞締顛掂滇碘點典靛墊電佃甸店惦奠澱殿碉叼雕凋刁掉吊釣調跌爹碟蝶叠諜疊丁盯叮釘頂鼎錠定訂丟東冬董懂動棟侗恫凍洞兜抖鬥陡豆逗痘都督毒犢獨讀堵睹賭杜鍍肚度渡妒端短鍛段斷緞堆兌隊對墩噸蹲敦頓囤鈍盾遁掇哆多奪垛躲朵跺舵剁惰墮蛾峨鵝俄額訛娥惡厄扼遏鄂餓恩而兒耳爾餌洱二貳發罰筏伐乏閥法琺藩帆番翻樊礬釩繁凡煩反返範販犯飯泛坊芳方肪房防妨仿訪紡放菲非啡飛肥匪誹吠肺廢沸費芬酚吩氛分紛墳焚汾粉奮份忿憤糞豐封楓蜂峰鋒風瘋烽逢馮縫諷奉鳳佛否夫敷膚孵扶拂輻幅氟符伏俘服浮涪福袱弗甫撫輔俯釜斧脯腑府腐赴副覆賦複傅付阜父腹負富訃附婦縛咐噶嘎該改概鈣蓋溉幹甘杆柑竿肝趕感稈敢贛岡剛鋼缸肛綱崗港杠篙臯高膏羔糕搞鎬稿告哥歌擱戈鴿胳疙割革葛格蛤閣隔鉻個各給根跟耕更庚羹埂耿梗工攻功恭龔供躬公宮弓鞏汞拱貢共鈎勾溝苟狗垢構購夠辜菇咕箍估沽孤姑鼓古蠱骨谷股故顧固雇刮瓜剮寡挂褂乖拐怪棺關官冠觀管館罐慣灌貫光廣逛瑰規圭矽歸龜閨軌鬼詭癸桂櫃跪貴劊輥滾棍鍋郭國果裹過哈骸孩海氦亥害駭酣憨邯韓含涵寒函喊罕翰撼捍旱憾悍焊汗漢夯杭航壕嚎豪毫郝好耗號浩呵喝荷菏核禾和何合盒貉閡河涸赫褐鶴賀嘿黑痕很狠恨哼亨橫衡恒轟哄烘虹鴻洪宏弘紅喉侯猴吼厚候後呼乎忽瑚壺葫胡蝴狐糊湖弧虎唬護互滬戶花嘩華猾滑畫劃化話槐徊懷淮壞歡環桓還緩換患喚瘓豢煥渙宦幻荒慌黃磺蝗簧皇凰惶煌晃幌恍謊灰揮輝徽恢蛔回毀悔慧卉惠晦賄穢會燴彙諱誨繪葷昏婚魂渾混豁活夥火獲或惑霍貨禍擊圾基機畸稽積箕肌饑迹激譏雞姬績緝吉極棘輯籍集及急疾汲即嫉級擠幾脊己薊技冀季伎祭劑悸濟寄寂計記既忌際妓繼紀嘉枷夾佳家加莢頰賈甲鉀假稼價架駕嫁殲監堅尖箋間煎兼肩艱奸緘繭檢柬堿鹼揀撿簡儉剪減薦檻鑒踐賤見鍵箭件健艦劍餞漸濺澗建僵姜將漿江疆蔣槳獎講匠醬降蕉椒礁焦膠交郊澆驕嬌嚼攪鉸矯僥腳狡角餃繳絞剿教酵轎較叫窖揭接皆稭街階截劫節莖睛晶鯨京驚精粳經井警景頸靜境敬鏡徑痙靖竟競淨炯窘揪究糾玖韭久灸九酒廄救舊臼舅咎就疚鞠拘狙疽居駒菊局咀矩舉沮聚拒據巨具距踞鋸俱句懼炬劇捐鵑娟倦眷卷絹撅攫抉掘倔爵桔傑捷睫竭潔結解姐戒藉芥界借介疥誡屆巾筋斤金今津襟緊錦僅謹進靳晉禁近燼浸盡勁荊兢覺決訣絕均菌鈞軍君峻俊竣浚郡駿喀咖卡咯開揩楷凱慨刊堪勘坎砍看康慷糠扛抗亢炕考拷烤靠坷苛柯棵磕顆科殼咳可渴克刻客課肯啃墾懇坑吭空恐孔控摳口扣寇枯哭窟苦酷庫褲誇垮挎跨胯塊筷儈快寬款匡筐狂框礦眶曠況虧盔巋窺葵奎魁傀饋愧潰坤昆捆困括擴廓闊垃拉喇蠟臘辣啦萊來賴藍婪欄攔籃闌蘭瀾讕攬覽懶纜爛濫琅榔狼廊郎朗浪撈勞牢老佬姥酪烙澇勒樂雷鐳蕾磊累儡壘擂肋類淚棱楞冷厘梨犁黎籬狸離漓理李裏鯉禮莉荔吏栗麗厲勵礫曆利傈例俐痢立粒瀝隸力璃哩倆聯蓮連鐮廉憐漣簾斂臉鏈戀煉練糧涼梁粱良兩輛量晾亮諒撩聊僚療燎寥遼潦了撂鐐廖料列裂烈劣獵琳林磷霖臨鄰鱗淋凜賃吝拎玲菱零齡鈴伶羚淩靈陵嶺領另令溜琉榴硫餾留劉瘤流柳六龍聾嚨籠窿隆壟攏隴樓婁摟簍漏陋蘆盧顱廬爐擄鹵虜魯麓碌露路賂鹿潞祿錄陸戮驢呂鋁侶旅履屢縷慮氯律率濾綠巒攣孿灤卵亂掠略掄輪倫侖淪綸論蘿螺羅邏鑼籮騾裸落洛駱絡媽麻瑪碼螞馬罵嘛嗎埋買麥賣邁脈瞞饅蠻滿蔓曼慢漫謾芒茫盲氓忙莽貓茅錨毛矛鉚卯茂冒帽貌貿麽玫枚梅酶黴煤沒眉媒鎂每美昧寐妹媚門悶們萌蒙檬盟錳猛夢孟眯醚靡糜迷謎彌米秘覓泌蜜密冪棉眠綿冕免勉娩緬面苗描瞄藐秒渺廟妙蔑滅民抿皿敏憫閩明螟鳴銘名命謬摸摹蘑模膜磨摩魔抹末莫墨默沫漠寞陌謀牟某拇牡畝姆母墓暮幕募慕木目睦牧穆拿哪呐鈉那娜納氖乃奶耐奈南男難囊撓腦惱鬧淖呢餒內嫩能妮霓倪泥尼擬你匿膩逆溺蔫拈年碾攆撚念娘釀鳥尿捏聶孽齧鑷鎳涅您檸獰凝甯擰濘牛扭鈕紐膿濃農弄奴努怒女暖虐瘧挪懦糯諾哦歐鷗毆藕嘔偶漚啪趴爬帕怕琶拍排牌徘湃派攀潘盤磐盼畔判叛乓龐旁耪胖抛咆刨炮袍跑泡呸胚培裴賠陪配佩沛噴盆砰抨烹澎彭蓬棚硼篷膨朋鵬捧碰坯砒霹批披劈琵毗啤脾疲皮匹痞僻屁譬篇偏片騙飄漂瓢票撇瞥拼頻貧品聘乒坪蘋萍平憑瓶評屏坡潑頗婆破魄迫粕剖撲鋪仆莆葡菩蒲埔樸圃普浦譜曝瀑期欺棲戚妻七淒漆柒沏其棋奇歧畦崎臍齊旗祈祁騎起豈乞企啓契砌器氣迄棄汽泣訖掐洽牽扡釺鉛千遷簽仟謙乾黔錢鉗前潛遣淺譴塹嵌欠歉槍嗆腔羌牆薔強搶橇鍬敲悄橋瞧喬僑巧鞘撬翹峭俏竅切茄且怯竊欽侵親秦琴勤芹擒禽寢沁青輕氫傾卿清擎晴氰情頃請慶瓊窮秋丘邱球求囚酋泅趨區蛆曲軀屈驅渠取娶齲趣去圈顴權醛泉全痊拳犬券勸缺炔瘸卻鵲榷確雀裙群然燃冉染瓤壤攘嚷讓饒擾繞惹熱壬仁人忍韌任認刃妊紉扔仍日戎茸蓉榮融熔溶容絨冗揉柔肉茹蠕儒孺如辱乳汝入褥軟阮蕊瑞銳閏潤若弱撒灑薩腮鰓塞賽三三傘散桑嗓喪搔騷掃嫂瑟色澀森僧莎砂殺刹沙紗傻啥煞篩曬珊苫杉山刪煽衫閃陝擅贍膳善汕扇繕墒傷商賞晌上尚裳梢捎稍燒芍勺韶少哨邵紹奢賒蛇舌舍赦攝射懾涉社設砷申呻伸身深娠紳神沈審嬸甚腎慎滲聲生甥牲升繩省盛剩勝聖師失獅施濕詩屍虱十石拾時什食蝕實識史矢使屎駛始式示士世柿事拭誓逝勢是嗜噬適仕侍釋飾氏市恃室視試收手首守壽授售受瘦獸蔬樞梳殊抒輸叔舒淑疏書贖孰熟薯暑曙署蜀黍鼠屬術述樹束戍豎墅庶數漱恕刷耍摔衰甩帥栓拴霜雙爽誰水睡稅吮瞬順舜說碩朔爍斯撕嘶思私司絲死肆寺嗣四伺似飼巳松聳慫頌送宋訟誦搜艘擻嗽蘇酥俗素速粟僳塑溯宿訴肅酸蒜算雖隋隨綏髓碎歲穗遂隧祟孫損筍蓑梭唆縮瑣索鎖所塌他它她塔獺撻蹋踏胎苔擡台泰酞太態汰坍攤貪癱灘壇檀痰潭譚談坦毯袒碳探歎炭湯塘搪堂棠膛唐糖倘躺淌趟燙掏濤滔縧萄桃逃淘陶討套特藤騰疼謄梯剔踢銻提題蹄啼體替嚏惕涕剃屜天添填田甜恬舔腆挑條迢眺跳貼鐵帖廳聽烴汀廷停亭庭挺艇通桐酮瞳同銅彤童桶捅筒統痛偷投頭透凸禿突圖徒途塗屠土吐兔湍團推頹腿蛻褪退吞屯臀拖托脫鴕陀馱駝橢妥拓唾挖哇蛙窪娃瓦襪歪外豌彎灣玩頑丸烷完碗挽晚皖惋宛婉萬腕汪王亡枉網往旺望忘妄威巍微危韋違桅圍唯惟爲濰維葦萎委偉僞尾緯未蔚味畏胃喂魏位渭謂尉慰衛瘟溫蚊文聞紋吻穩紊問嗡翁甕撾蝸渦窩我斡臥握沃巫嗚鎢烏汙誣屋無蕪梧吾吳毋武五捂午舞伍侮塢戊霧晤物勿務悟誤昔熙析西硒矽晰嘻吸錫犧稀息希悉膝夕惜熄烯溪汐犀檄襲席習媳喜銑洗系隙戲細瞎蝦匣霞轄暇峽俠狹下廈夏嚇掀鍁先仙鮮纖鹹賢銜舷閑涎弦嫌顯險現獻縣腺餡羨憲陷限線相廂鑲香箱襄湘鄉翔祥詳想響享項巷橡像向象蕭硝霄削哮囂銷消宵淆曉小孝校肖嘯笑效楔些歇蠍鞋協挾攜邪斜脅諧寫械卸蟹懈泄瀉謝屑薪芯鋅欣辛新忻心信釁星腥猩惺興刑型形邢行醒幸杏性姓兄凶胸匈洶雄熊休修羞朽嗅鏽秀袖繡墟戌需虛噓須徐許蓄酗敘旭序畜恤絮婿緒續軒喧宣懸旋玄選癬眩絢靴薛學穴雪血勳熏循旬詢尋馴巡殉汛訓訊遜迅壓押鴉鴨呀丫芽牙蚜崖衙涯雅啞亞訝焉咽閹煙淹鹽嚴研蜒岩延言顔閻炎沿奄掩眼衍演豔堰燕厭硯雁唁彥焰宴諺驗殃央鴦秧楊揚佯瘍羊洋陽氧仰癢養樣漾邀腰妖瑤搖堯遙窯謠姚咬舀藥要耀椰噎耶爺野冶也頁掖業葉曳腋夜液一壹醫揖銥依伊衣頤夷遺移儀胰疑沂宜姨彜椅蟻倚已乙矣以藝抑易邑屹億役臆逸肄疫亦裔意毅憶義益溢詣議誼譯異翼翌繹茵蔭因殷音陰姻吟銀淫寅飲尹引隱印英櫻嬰鷹應纓瑩螢營熒蠅迎贏盈影穎硬映喲擁傭臃癰庸雍踴蛹詠泳湧永恿勇用幽優悠憂尤由郵鈾猶油遊酉有友右佑釉誘又幼迂淤于盂榆虞愚輿余俞逾魚愉渝漁隅予娛雨與嶼禹宇語羽玉域芋郁籲遇喻峪禦愈欲獄育譽浴寓裕預豫馭鴛淵冤元垣袁原援轅園員圓猿源緣遠苑願怨院曰約越躍鑰嶽粵月悅閱耘雲鄖勻隕允運蘊醞暈韻孕匝砸雜栽哉災宰載再在咱攢暫贊贓髒葬遭糟鑿藻棗早澡蚤躁噪造皂竈燥責擇則澤賊怎增憎曾贈紮喳渣劄軋鍘閘眨柵榨咋乍炸詐摘齋宅窄債寨瞻氈詹粘沾盞斬輾嶄展蘸棧占戰站湛綻樟章彰漳張掌漲杖丈帳賬仗脹瘴障招昭找沼趙照罩兆肇召遮折哲蟄轍者鍺蔗這浙珍斟真甄砧臻貞針偵枕疹診震振鎮陣蒸掙睜征猙爭怔整拯正政幀症鄭證芝枝支吱蜘知肢脂汁之織職直植殖執值侄址指止趾只旨紙志摯擲至致置幟峙制智秩稚質炙痔滯治窒中盅忠鍾衷終種腫重仲衆舟周州洲謅粥軸肘帚咒皺宙晝驟珠株蛛朱豬諸誅逐竹燭煮拄矚囑主著柱助蛀貯鑄築住注祝駐抓爪拽專磚轉撰賺篆樁莊裝妝撞壯狀椎錐追贅墜綴諄准捉拙卓桌琢茁酌啄著灼濁茲咨資姿滋淄孜紫仔籽滓子自漬字鬃棕蹤宗綜總縱鄒走奏揍租足卒族祖詛阻組鑽纂嘴醉最罪尊遵昨左佐柞做作坐座" ;
    }
    public String traditionalized(String cc){
        String  str= "";
        for(int i=0;i <cc.length();i++){
          if(charPYStr().indexOf(cc.charAt(i))!=-1)
            str+=ftPYStr().charAt(charPYStr().indexOf(cc.charAt(i)));
          else
            str+=cc.charAt(i);
        }
        return str;
    }

   public String simplized(String cc) {
       String str = "";
       for (int i = 0; i < cc.length(); i++) {
           if (ftPYStr().indexOf(cc.charAt(i)) != -1)
               str += charPYStr().charAt(ftPYStr().indexOf(cc.charAt(i)));
           else
               str += cc.charAt(i);
       }
       return str;
   }
   /***
    * 生成圖片
    * @param sql sql語句 ; imag  圖片欄位 ; url 存取路徑
    * @return result 正確的語言
    * @author sime
    * **/
   public void rpicture(String sql,String imag,String url) throws Exception {
	   byte[] Buffer = new byte[4096];
       String sql1 = sql;
        ResultSet rs1 = this.executeQuery("info6",sql1);
        if(rs1.next()) {
            File file = new File(url);
               if (!file.exists()) {
                file.createNewFile(); // 如果文件不存在，则创建
               }
               FileOutputStream  fos = new FileOutputStream(file);
               InputStream is = rs1.getBinaryStream(imag);
               int size = 0;
               
               while ((size = is.read(Buffer)) != -1) {
                // System.out.println(size);
                fos.write(Buffer, 0, size);
               }
               fos.close();
               rs1.close();
        }
   }
   public ResultSet executePagingQuery2(String serverName, String sql 
		 ) throws Exception {
	//System.out.println("------1----");
	int page = this.getIntParam("_page");
	//System.out.println("------2----");
	// System.out.println(this.parsePagingSql(sql, page, uniqueColumn));
	return this.executeQuery(serverName, this.parsePagingSql2(sql, page,
			 serverName));
	}
   /**
	 * 重新湊出分頁SQL語句. 
	 */
	private String parsePagingSql2(String str, int page,  String serverName) throws Exception{
		//System.out.println("------3----");
		String[] pagingSql = this.splitPagingSql(str);
		String num = pagingSql[0];
	//	System.out.println("------6----");
		String showColumn = pagingSql[1];
		String fromWhere = pagingSql[2];
		String groupBy = pagingSql[3];
		String orderBy = pagingSql[4];
	 // System.out.println("weiwei----"+getPagingData( serverName,str)[0]);
	//	System.out.println("weiwei----"+pagingSql[0]+","+pagingSql[1]+","+pagingSql[2]);
		page = (page < 1) ? 1 : page; // page 最小 = 1.
		StringBuffer sb = new StringBuffer();
		sb.append("select * from (");
		if(Integer.parseInt(num)*page > getPagingData( serverName,str)[0]){
			sb.append("select top ").append(Integer.parseInt(num)-(Integer.parseInt(num)*page-getPagingData( serverName,str)[0])).append(" ").append("*")
			  .append(" from (").append("select top ")
		      .append( getPagingData( serverName,str)[0]+" ");
		}else{
			sb.append("select top ").append(num).append(" ").append("*")
			  .append(" from (").append("select top ")
			  .append( Integer.parseInt(num)*page +" ");
		}
		//System.out.println("------7----");
	    sb.append(showColumn).append(" from ").append(fromWhere);
	    if (groupBy.length() != 0) { 
	    	sb.append(" group by ").append(groupBy);
	    }
	    if(orderBy.length()!=0){
		   sb.append(" order by ").append(orderBy).append(" desc ") ;
	    }
		sb.append(")x "); 
		if(orderBy.length()!=0){
			sb.append(" order by ").append(orderBy ); 
		}
		sb.append(")y "); 
		if(orderBy.length()!=0){
			sb.append(" order by ").append(orderBy ).append(" desc ")  ;
		}
		//System.out.println(sb.toString());
		return sb.toString();
	}
	/*****************************************************************************
	 *将Double型数据后的零去掉
	 * 
	 ********************************************************************************/
	public  String  removeZero(String number) {
		// System.out.println(number );
		 if(number.contains(".")) {
			 if(number.replace(".","/").split("/")[1].equals("0")) {
				// System.out.println(number.replace(".","/").split("/")[0]);
				 return number.replace(".","/").split("/")[0];
			  }			  
		 } 	  
	     return number;		  
	}
	
	public  String  removeZero(Double number) {
        String num = number + "";
        return num = this.removeZero(num);
	}
	public String formatEuDate(String sdate,String bj) {//明國時間轉西元時間//dwei
        String lstvd = "";
            if(!sdate.equals("")) {
                    String lstvd1[] = sdate.split(bj);
                    lstvd = lstvd + (Integer.parseInt(lstvd1[0]) + 1911);
                    lstvd = lstvd + bj + ((Integer.parseInt(lstvd1[1].equals("")?"1":lstvd1[1]) + 100)+"").substring(1,3);
                    lstvd = lstvd + bj + ((Integer.parseInt(lstvd1[2].equals("")?"1":lstvd1[2]) + 100)+"").substring(1,3);
            } 
            //System.out.print("lstvd:"+lstvd);
        return lstvd;
	}
	public String formatTwDate(String sdate,String bj) {//西元時間轉明國時間//dwei
        String lstvd = "";
        if(!sdate.equals("")) {
                    String lstvd1[] = sdate.split(bj);
                    if((Integer.parseInt(lstvd1[0]) - 1911)>=100){
                    	lstvd = lstvd + "0" + (Integer.parseInt(lstvd1[0]) - 1911);
                    }else if((Integer.parseInt(lstvd1[0]) - 1911)>=10){
                    	lstvd = lstvd + "00" + (Integer.parseInt(lstvd1[0]) - 1911);
                    }else {
                    	lstvd = lstvd + "000" + (Integer.parseInt(lstvd1[0]) - 1911);
                    }
                    //lstvd = lstvd + ((Integer.parseInt(lstvd1[0]) - 1911)>=100?"0":"00") + (Integer.parseInt(lstvd1[0]) - 1911);
                    lstvd = lstvd + bj + ((Integer.parseInt(lstvd1[1].equals("")?"1":lstvd1[1]) + 100)+"").substring(1,3);
                    lstvd = lstvd + bj + ((Integer.parseInt(lstvd1[2].equals("")?"1":lstvd1[2]) + 100)+"").substring(1,3);
            } 
            //System.out.print("lstvd:"+lstvd);
        return lstvd;
	}
	
	
	/**
	 * @param str
	 * @return boolean
	 * @author yanjie
	 */
	public boolean isEmpty(String str){
		return str == null || str.length() == 0 || "null".equalsIgnoreCase(str) ;
	}
	
	/**
	 * @param rs (rs.getString(1) for value , rs.getString(2) for display value)
	 * @return
	 * @throws SQLException
	 */
	public String[][] getDropDownArrayByResult(ResultSet rs) throws SQLException {
		if(rs == null)
			return null ;
		
		List list1 = new ArrayList();
		List list2 = new ArrayList();
		while(rs.next()){
			list1.add(rs.getString(1));
			list2.add(rs.getString(2));
		}
		
		return new String[][]{(String[])list1.toArray(new String[]{}),(String[])list2.toArray(new String[]{})};
	}
	
	/**
	 * @param mainOption  (mainOption[0] value array mainOption[1] display value array)
	 * @param firstOption (firstOption[0] value firstOption[1] display value)
	 * @param value
	 * @param property
	 * @return
	 * @throws Exception
	 * @author yanjie
	 */
	public String getDropDownHTML(String[][] mainOption,String[] firstOption,String value,String property) throws Exception{
		if(mainOption == null || mainOption.length != 2)
			return null ;
		
		 StringBuffer temp = new StringBuffer();
         boolean isValInRs = (value == null || value.length() == 0); // 如果有 value, 那麼 預設false, 去做檢查.
         
         for (int i = 0; i < mainOption[0].length; i++) {
             temp.append("<option");
             temp.append(appendAttrib("value", mainOption[0][i]));
             
             if (!isValInRs && mainOption[0][i].equalsIgnoreCase(value)) { // 如果不存在, 就判斷.
                 isValInRs = true;
                 temp.append(appendAttrib("selected", "selected"));
             }
             temp.append(">");
             temp.append(mainOption[1][i]);
             temp.append("</option>\n");
         }

         // 列出結果.
         StringBuffer sb = new StringBuffer();
         sb.append("<select ");
         sb.append(property);
         sb.append(">\n");
         if (!isValInRs) { // 如果不存在 就列在第一筆.
             sb.append("<option");
             sb.append(appendAttrib("value", value));
             sb.append(">");
             sb.append(value);
             sb.append("</option>\n");
         }
         if(firstOption != null){
        	 sb.append("<option");
             sb.append(appendAttrib("value", firstOption[0]));
             sb.append(">");
             sb.append(firstOption[1]);
             sb.append("</option>\n");
         }
         sb.append(temp);
         sb.append("</select>");
		return sb.toString();
	}
	
	public boolean isAtuMail(String mail){
		mail = mail.toLowerCase();
		return   mail.indexOf("@jingmeng.vn") >= 0 
        		|| mail.indexOf("@mail.jrknit.com") >= 0
        		|| mail.indexOf("@mail.js.com.tw") >= 0
        		|| mail.indexOf("@qd.jmknit.com") >= 0
        		|| mail.indexOf("@jh.jmknit.com") >= 0
        		|| mail.indexOf("@mail.jingchain.com") >= 0 ;
	}
	
	 public String i18n(String str) throws Exception {
    	String result = str.trim();
    	return result ;
    }
	
}
